[BZOJ2120]数颜色

题目大意:
  给你一个长度为$n$的正整数序列$A(A_i\leq10^6)$。
  给出$m$次操作,操作包含以下两种:
    1.将$A_p$上的数修改为$c$;
    2.询问区间$[l,r]$中不同数的个数。
思路:
  带修莫队。
  对于询问区间下标,每$n^\frac{2}{3}$个为一块,共分为$n^\frac{1}{3}$块。
  首先对于询问下标按块排序,对于左右端点所属块对应相同的,按时间先后排序。
  离线处理询问时,区间的转移就是普通莫队的转移。时间的转移暴力修改。

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<algorithm>
 5 inline int getint() {
 6     register char ch;
 7     while(!isdigit(ch=getchar()));
 8     register int x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return x;
11 }
12 inline char getalpha() {
13     register char ch;
14     while(!isalpha(ch=getchar()));
15     return ch;
16 }
17 const int N=10001,MAX=1000001;
18 int tot,a[N],b[N],bel[N],ans[N],cnt[MAX],tmp;
19 struct Query {
20     int l,r,t,id;
21     bool operator < (const Query &another) const {
22         if(bel[l]==bel[another.l]) {
23             if(bel[r]==bel[another.r]) {
24                 return t<another.t;
25             }
26             return bel[r]<bel[another.r];
27         }
28         return bel[l]<bel[another.l];
29     }
30 };
31 Query q[N];
32 struct Modify {
33     int p,c,last;
34 };
35 Modify mo[N];
36 inline void ins(const int &x) {
37     if(!cnt[a[x]]++) tmp++;
38 }
39 inline void del(const int &x) {
40     if(!--cnt[a[x]]) tmp--;
41 }
42 int main() {
43     const int n=getint(),m=getint(),block=pow(n,2./3);
44     for(register int i=1;i<=n;i++) {
45         a[i]=b[i]=getint();
46         bel[i]=i/block;
47     }
48     for(register int i=0;i<m;i++) {
49         const char opt=getalpha();
50         if(opt=='Q') {
51             const int l=getint(),r=getint();
52             q[i-tot]=(Query){l,r,tot,i-tot};
53         }
54         if(opt=='R') {
55             const int p=getint(),c=getint();
56             mo[++tot]=(Modify){p,c,b[p]};
57             b[p]=c;
58         }
59     }
60     std::sort(&q[0],&q[m-tot]);
61     for(register int i=0,l=1,r=0,t=0;i<m-tot;i++) {
62         while(r<q[i].r) ins(++r);
63         while(l>q[i].l) ins(--l);
64         while(r>q[i].r) del(r--);
65         while(l<q[i].l) del(l++);
66         while(t<q[i].t) {
67             t++;
68             if(l<=mo[t].p&&mo[t].p<=r) {
69                 del(mo[t].p);
70                 a[mo[t].p]=mo[t].c;
71                 ins(mo[t].p);
72             } else {
73                 a[mo[t].p]=mo[t].c;
74             }
75         }
76         while(t>q[i].t) {
77             if(l<=mo[t].p&&mo[t].p<=r) {
78                 del(mo[t].p);
79                 a[mo[t].p]=mo[t].last;
80                 ins(mo[t].p);
81             } else {
82                 a[mo[t].p]=mo[t].last;
83             }
84             t--;
85         }
86         ans[q[i].id]=tmp;
87     }
88     for(register int i=0;i<m-tot;i++) {
89         printf("%d\n",ans[i]);
90     }
91     return 0;
92 }

 

posted @ 2018-02-07 16:03  skylee03  阅读(109)  评论(0编辑  收藏  举报