Cod sursa(job #3311649)

Utilizator BuzdiBuzdugan Rares Andrei Buzdi Data 23 septembrie 2025 16:46:50
Problema Marbles Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.15 kb
#include <bits/stdc++.h>
using namespace std;

const int VMAX = 64;

struct Query { int type, i, j; };

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    ifstream fin("marbles.in");
    ofstream fout("marbles.out");

    int n, m;
    fin >> n >> m;

    vector<pair<int,int>> initial;
    initial.reserve(n);
    vector<Query> queries;
    queries.reserve(m);

    vector<int> coords;
    coords.reserve(n + 2*m + 5);

    // read initial marbles
    for (int k = 0; k < n; ++k) {
        int x, c; fin >> x >> c;
        initial.emplace_back(x,c);
        coords.push_back(x);
    }

    // read queries and collect all coordinates that might be referenced
    for (int k = 0; k < m; ++k) {
        int type, i, j; fin >> type >> i >> j;
        queries.push_back({type, i, j});
        coords.push_back(i);
        if (type == 0) coords.push_back(i + j); // target position
        else coords.push_back(j); // range end
    }

    // coordinate compress
    sort(coords.begin(), coords.end());
    coords.erase(unique(coords.begin(), coords.end()), coords.end());
    int S = (int)coords.size();

    auto getIndex = [&](int x) -> int {
        // compressed index 1..S
        return int(lower_bound(coords.begin(), coords.end(), x) - coords.begin()) + 1;
    };

    // Fenwick trees: bit[color][index], colors 1..VMAX, indices 1..S
    vector<vector<int>> bit(VMAX + 1, vector<int>(S + 1, 0));

    auto bit_add = [&](int color, int idx, int delta) {
        for (int x = idx; x <= S; x += x & -x) bit[color][x] += delta;
    };

    auto bit_sum = [&](int color, int idx) {
        int s = 0;
        for (int x = idx; x > 0; x -= x & -x) s += bit[color][x];
        return s;
    };

    // current color at each compressed position (0 if empty)
    vector<int> colorAt(S + 1, 0);

    // initialize
    for (auto &p : initial) {
        int x = p.first, c = p.second;
        int idx = getIndex(x);
        colorAt[idx] = c;
        bit_add(c, idx, 1);
    }

    // process queries
    for (auto &q : queries) {
        if (q.type == 0) {
            int pos = q.i;
            int shift = q.j;
            int idx_from = getIndex(pos);
            int c = colorAt[idx_from];
            // remove from old position
            if (c != 0) {
                bit_add(c, idx_from, -1);
                colorAt[idx_from] = 0;
            } else {
                // Assuming input is valid (there is always a marble at pos).
                // If invalid input is possible, handle error or continue.
            }
            int pos_to = pos + shift;
            int idx_to = getIndex(pos_to);
            bit_add(c, idx_to, +1);
            colorAt[idx_to] = c;
        } else {
            int L = q.i, R = q.j;
            if (L > R) swap(L, R);
            int idxL = getIndex(L);
            int idxR = getIndex(R);
            int ans = 0;
            for (int c = 1; c <= VMAX; ++c) {
                int cnt = bit_sum(c, idxR) - bit_sum(c, idxL - 1);
                if (cnt > ans) ans = cnt;
            }
            fout << ans << '\n';
        }
    }

    return 0;
}