• 洛谷 P1903 [国家集训队]数颜色 / 维护队列 题解


    \(Description\)

    Luogu传送门

    \(Solution\)

    带修莫队板子题。

    就是再多开一维时间轴,把每次修改修改前的颜色和修改后的颜色都记录下来。

    离线处理。

    枚举操作时,类似于普通的莫队,while(操作时间) 看看是该插入还是删除,然后直接修改就完了。

    贴下代码吧,直接看代码比较好理解。

    \(Code\)

    #include <bits/stdc++.h>
    #define get_B(x) x / B
    
    using namespace std;
    
    namespace IO{
        inline int read(){
            int x = 0;
            char ch = getchar();
            while(!isdigit(ch)) ch = getchar();
            while(isdigit(ch)) x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
            return x;
        }
    
        template <typename T> inline void write(T x){
            if(x > 9) write(x / 10);
            putchar(x % 10 + '0');
        }
    }
    using namespace IO;
    
    const int N = 2e5 + 10;
    const int M = 1e6 + 10;
    int n, m, B, res;
    int c[N], col[N];
    char op[3];
    struct Upd{
        int pos, col, pre;
    }p[N];
    struct Qry{
        int l, r, t, pos;
        friend bool operator < (Qry a, Qry b){
            if(get_B(a.l) != get_B(b.l)) return get_B(a.l) < get_B(b.l);
            return get_B(a.r) != get_B(b.r) ? get_B(a.r) < get_B(b.r) : a.t < b.t;
        }
    }q[N];
    int tp, tq;
    int vis[M], ans[N];
    
    int main(){
        n = read(), m = read();
        for(int i = 1; i <= n; ++i) col[i] = c[i] = read();
        for(int i = 1; i <= m; ++i){
            scanf("%s", op);
            int x = read(), y = read();
            if(op[0] == 'R') p[++tp] = (Upd){x, y, c[x]}, c[x] = y;
            else q[++tq] = (Qry){x, y, tp, tq};
        }
        if(!tq) return 0;
        B = pow(n, 0.7);
        sort(q + 1, q + 1 + tq);
        int l = 1, r = 0, t = 0;
        for(int i = 1; i <= tq; ++i){
            while(l > q[i].l) res += !vis[col[--l]]++;
            while(l < q[i].l) res -= !--vis[col[l++]];
            while(r < q[i].r) res += !vis[col[++r]]++;
            while(r > q[i].r) res -= !--vis[col[r--]];
            while(t > q[i].t){
                int x = p[t].pos;
                if(l <= x && x <= r) res -= !--vis[col[x]];
                col[x] = p[t--].pre;
                if(l <= x && x <= r) res += !vis[col[x]]++;
            }
            while(t < q[i].t){
                int x = p[++t].pos;
                if(l <= x && x <= r) res -= !--vis[col[x]];
                col[x] = p[t].col;
                if(l <= x && x <= r) res += !vis[col[x]]++;
            }
            ans[q[i].pos] = res;
        }
        for(int i = 1; i <= tq; ++i) write(ans[i]), puts("");
        return 0;
    }
    

    \[\_EOF\_ \]

  • 相关阅读:
    hdu 4370
    lightoj 1074
    poj 1026
    poj 3159
    poj3660 cow contest
    hdu 4069 垃圾数独
    操作系统概念题复习
    ARM指令
    C++ 抢占时优先级进程调度
    Docker 入门
  • 原文地址:https://www.cnblogs.com/xixike/p/15782736.html
Copyright © 2020-2023  润新知