带时间戳的莫队
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(" "); 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 ",ans[i]); 57 return 0; 58 }