Cod sursa(job #3311653)

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

const int VMAX = 64;

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

struct Fenwick {
    vector<int> f;
    Fenwick() {}
    Fenwick(int n): f(n+1, 0) {}
    void add(int i, int delta){
        for(; i < (int)f.size(); i += i & -i) f[i] += delta;
    }
    int sum(int i){
        int s = 0;
        for(; i > 0; i -= i & -i) s += f[i];
        return s;
    }
    int range_sum(int l, int r){ // inclusive indices (1-based)
        if(r < l) return 0;
        return sum(r) - sum(l-1);
    }
};

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);
    for(int k=0;k<n;k++){
        int x,c; fin >> x >> c;
        initial.emplace_back(x,c);
    }

    vector<Query> queries;
    queries.reserve(m);
    for(int k=0;k<m;k++){
        int t,i,j; fin >> t >> i >> j;
        queries.push_back({t,i,j});
    }

    // --- First pass: simulate to collect coords per color ---
    // map current pos -> color
    unordered_map<int,int> pos2color;
    pos2color.reserve(n*2 + 10);
    for(auto &p : initial) pos2color[p.first] = p.second;

    // coords per color (raw, may contain duplicates)
    vector<vector<int>> coords(VMAX+1);
    for(auto &p : initial) coords[p.second].push_back(p.first);

    for(auto &q : queries){
        if(q.type == 0){
            int from = q.i;
            int shift = q.j;
            auto it = pos2color.find(from);
            if(it == pos2color.end()){
                // invalid input assumption: no marble at position `from`
                // skip (or handle as needed). Here we skip.
                continue;
            }
            int c = it->second;
            pos2color.erase(it);
            int to = from + shift;
            pos2color[to] = c;
            coords[c].push_back(to);
        } else {
            // query: nothing to collect
        }
    }

    // compress per-color coordinates (unique & sorted)
    for(int c = 1; c <= VMAX; ++c){
        auto &v = coords[c];
        if(v.empty()) continue;
        sort(v.begin(), v.end());
        v.erase(unique(v.begin(), v.end()), v.end());
    }

    // build per-color Fenwick trees
    vector<Fenwick> bit(VMAX+1);
    for(int c = 1; c <= VMAX; ++c){
        if(!coords[c].empty()){
            bit[c] = Fenwick((int)coords[c].size());
        }
    }

    // helper: get 1-based compressed index of pos in coords[c], or -1 if not present
    auto get_idx = [&](int c, int pos)->int{
        auto &v = coords[c];
        if(v.empty()) return -1;
        int p = int(lower_bound(v.begin(), v.end(), pos) - v.begin());
        if(p < (int)v.size() && v[p] == pos) return p + 1;
        return -1;
    };

    // --- Initialize BITs from initial positions ---
    // rebuild pos2color from initial
    pos2color.clear();
    for(auto &p : initial){
        int x = p.first, c = p.second;
        pos2color[x] = c;
        int idx = get_idx(c, x);
        if(idx != -1) bit[c].add(idx, 1);
    }

    // --- Second pass: answer queries and perform updates ---
    for(auto &q : queries){
        if(q.type == 0){
            int from = q.i;
            int shift = q.j;
            auto it = pos2color.find(from);
            if(it == pos2color.end()){
                // no marble at 'from' (invalid input); ignore
                continue;
            }
            int c = it->second;
            // remove at 'from'
            int idx_from = get_idx(c, from);
            if(idx_from != -1) bit[c].add(idx_from, -1);
            pos2color.erase(it);

            int to = from + shift;
            pos2color[to] = c;
            int idx_to = get_idx(c, to);
            if(idx_to != -1) bit[c].add(idx_to, 1);
        } else {
            int L = q.i, R = q.j;
            if(L > R) swap(L, R);
            int best = 0;
            for(int c = 1; c <= VMAX; ++c){
                if(coords[c].empty()) continue;
                // find first index >= L
                int lpos = int(lower_bound(coords[c].begin(), coords[c].end(), L) - coords[c].begin()); // 0-based
                int rpos = int(upper_bound(coords[c].begin(), coords[c].end(), R) - coords[c].begin()) - 1; // 0-based
                if(lpos > rpos) continue;
                int lidx = lpos + 1;
                int ridx = rpos + 1;
                int cnt = bit[c].range_sum(lidx, ridx);
                if(cnt > best) best = cnt;
            }
            fout << best << '\n';
        }
    }

    return 0;
}