P1903 [国家集训队]数颜色 / 维护队列

带时间戳的莫队

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 using namespace std;
 5 #define fo(a,b,c) for(int a=b;a<=c;a++)
 6 #define go(a,b,c) for(int a=b;a>=c;a--)
 7 int read(){
 8     int a=0,f=0;char c=getchar();
 9     for(;c<'0'||c>'9';c=getchar())if(c=='-')f=1;
10     for(;c>='0'&&c<='9';c=getchar())a=a*10+c-'0';
11     return f?-a:a;
12 }
13 const int N=10001;
14 int a[N],p[1000001],ans[N],divi;
15 struct nod{int pla,pre,suc;}cg[N];
16 struct node{int l,r,t,bel;}ls[N];
17 int cmp(node a,node b){
18     if(a.l/divi!=b.l/divi)return a.l/divi<b.l/divi;
19     if(a.r/divi!=b.r/divi)return a.r/divi<b.r/divi;
20     return a.t<b.t; 
21 }
22 int main(){
23     int n=read(),m=read(),ln=0,tn=0,l=1,r=0,t=0,num=0;
24     fo(i,1,n)a[i]=read();
25     fo(i,1,m){
26         scanf("\n");
27         if(getchar()=='R'){//如果读入修改则记录修改的地点,修改前的数字和修改后的数字
28             ++tn;cg[tn].pla=read(),cg[tn].suc=read();
29             cg[tn].pre=a[cg[tn].pla];
30             a[cg[tn].pla]=cg[tn].suc;
31         } 
32         else ls[++ln]=(node){read(),read(),tn,ln};
33     }
34     divi=ceil(exp((log(n)+log(tn))/3));//分块大小
35     go(i,tn,1)a[cg[i].pla]=cg[i].pre;
36     sort(ls+1,ls+ln+1,cmp);
37     fo(i,1,m){
38         while(ls[i].l<l)num+=!p[a[--l]]++;
39         while(ls[i].l>l)num-=!--p[a[l++]];//l移动
40         while(ls[i].r>r)num+=!p[a[++r]]++;
41         while(ls[i].r<r)num-=!--p[a[r--]];//r移动
42         while(ls[i].t<t){
43             int pla=cg[t].pla;
44             if(l<=pla&&pla<=r)num-=!--p[a[pla]];
45             a[pla]=cg[t--].pre;
46             if(l<=pla&&pla<=r)num+=!p[a[pla]]++;
47         };
48         while(ls[i].t>t){
49             int pla=cg[++t].pla;
50             if(l<=pla&&pla<=r)num-=!--p[a[pla]];
51             a[pla]=cg[t].suc;
52             if(l<=pla&&pla<=r)num+=!p[a[pla]]++;
53         };//t移动
54         ans[ls[i].bel]=num;
55     }
56     fo(i,1,ln)printf("%d\n",ans[i]); 
57     return 0;
58 }

 

posted @ 2019-07-24 12:22  喵呜,颜儿ღ  阅读(165)  评论(0编辑  收藏  举报