数颜色「国家集训队」

题意

待修莫队模板题


思路

待修莫队在普通莫队的基础上,额外维护一个修改操作,每一次根据查询操作的时间加入修改或是撤销修改。

实现蛮显然的,配合代码很容易搞懂。

note:块大小的证明参见这里,此处不做赘述。

代码

#include <bits/stdc++.h>

using namespace std;

namespace StandardIO {

    template<typename T>inline void read (T &x) {
        x=0;T f=1;char c=getchar();
        for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
        for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
        x*=f;
    }

    template<typename T>inline void write (T x) {
        if (x<0) putchar('-'),x*=-1;
        if (x>=10) write(x/10);
        putchar(x%10+'0');
    }

}

using namespace StandardIO;

namespace Project {
    
    const int N=200200;
    
    int n,m,block;
    int a[N];
    int qcnt,ucnt;
    struct ask {
        int l,r,t,id;
    } q[N];
    struct upd {
        int x,pre,now;
    } u[N];
    int cnt[1000001],ans[N],res;
    
    inline bool cmp (const ask x,const ask y) {
        return (x.l/block!=y.l/block)?(x.l/block<y.l/block):((x.r/block!=y.r/block)?(x.r/block<y.r/block):x.t<y.t);
    }

    inline void MAIN () {
        read(n),read(m);
        for (register int i=1; i<=n; ++i) 
            read(a[i]);
        for (register int i=1; i<=m; ++i) {
            scanf("\n");
            if (getchar()=='Q') {
                ++qcnt,read(q[qcnt].l),read(q[qcnt].r),q[qcnt].t=ucnt,q[qcnt].id=qcnt;
            } else {
                ++ucnt,read(u[ucnt].x),read(u[ucnt].now),u[ucnt].pre=a[u[ucnt].x],a[u[ucnt].x]=u[ucnt].now;
            }
        }
        for (register int i=ucnt; i; --i) 
            a[u[i].x]=u[i].pre;
        block=ceil(exp((log(n)+log(ucnt))/3)),sort(q+1,q+qcnt+1,cmp);
        int l=1,r=0,t=0;
        for (register int i=1; i<=qcnt; ++i) {
            while (l>q[i].l) res+=!cnt[a[--l]]++;
            while (l<q[i].l) res-=!--cnt[a[l++]];
            while (r<q[i].r) res+=!cnt[a[++r]]++;
            while (r>q[i].r) res-=!--cnt[a[r--]];
            while (q[i].t<t) {
                int x=u[t].x;
                if (l<=x&&x<=r) res-=!--cnt[a[x]];
                a[x]=u[t--].pre;
                if (l<=x&&x<=r) res+=!cnt[a[x]]++;
            }
            while (q[i].t>t) {
                int x=u[++t].x;
                if (l<=x&&x<=r) res-=!--cnt[a[x]];
                a[x]=u[t].now;
                if (l<=x&&x<=r) res+=!cnt[a[x]]++;
            }
            ans[q[i].id]=res;
        }
        for (register int i=1; i<=qcnt; ++i) {
            write(ans[i]),puts("");
        }
    }
    
}

int main () {
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    Project::MAIN();
}

猜你喜欢

转载自www.cnblogs.com/ilverene/p/11729665.html