首先这题暴力可过,没事干就别写正解。。。
正解是三维带修改莫队,在普通莫队基础上再加上一个时间维,作为第三关键字参与排序,但是时间的转移十分蛋痛。。。
如果时间转移的下标在[L,R]内,就要对ans进行维护,同时对数组修改。如果不在,就只对数组修改。。。
code:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; struct hp{ int st,l,r,tim,num; }qst[100001]; int L,R,TIM,n,m,ans=0,a[100001],b[200002],c[100001]; int num[100001],change[100001][3],size,ansi[100001]; int cmp(const hp &a,const hp &b) { if ((a.st<b.st)||(a.st==b.st&&a.r<b.r)||(a.st==b.st&&b.r==a.r&&a.tim<b.tim)) return 1; else return 0; } void work(int i) { int l=qst[i].l,r=qst[i].r,tim=qst[i].tim; if (l!=r) { while (L<l) { if (num[a[L]]==1) ans--; num[a[L]]--; L++; } while (L>l) { L--; if (!num[a[L]]) ans++; num[a[L]]++; } while (R<r) { R++; if (!num[a[R]]) ans++; num[a[R]]++; } while (R>r) { if (num[a[R]]==1) ans--; num[a[R]]--; R--; } } while (tim>TIM) { TIM++; if (L<=change[TIM][0]&&change[TIM][0]<=R) { num[change[TIM][1]]--; if (num[change[TIM][1]]==0) ans--; num[change[TIM][2]]++; if (num[change[TIM][2]]==1) ans++; } a[change[TIM][0]]=change[TIM][2]; } while (tim<TIM) { if (L<=change[TIM][0]&&change[TIM][0]<=R) { num[change[TIM][2]]--; if (num[change[TIM][2]]==0) ans--; num[change[TIM][1]]++; if (num[change[TIM][1]]==1) ans++; } a[change[TIM][0]]=change[TIM][1]; TIM--; } if (qst[i].num) ansi[qst[i].num]=ans; } int main() { int i,per,numi=0,time=0; char opt; scanf("%d%d",&n,&m); per=sqrt(n); for (i=1;i<=n;++i) { scanf("%d",&a[i]); c[i]=b[i]=a[i]; } b[0]=n; for (i=1;i<=m;++i) { scanf("%c",&opt); while (opt!='Q'&&opt!='R') scanf("%c",&opt); if (opt=='Q') { scanf("%d%d",&qst[i].l,&qst[i].r); qst[i].st=qst[i].l/per+1; qst[i].num=++numi; qst[i].tim=time; } if (opt=='R') { time++; scanf("%d%d",&qst[i].l,&change[time][2]); qst[i].r=qst[i].l; qst[i].st=qst[i].l/per+1; qst[i].tim=time; qst[i].num=0; change[time][0]=qst[i].l; change[time][1]=c[qst[i].l]; c[qst[i].l]=change[time][2]; b[++b[0]]=change[time][2]; } } sort(b+1,b+b[0]+1); size=unique(b+1,b+b[0]+1)-b-1; for (i=1;i<=n;++i) a[i]=upper_bound(b+1,b+size+1,a[i])-b-1; for (i=1;i<=time;++i) { change[i][1]=upper_bound(b+1,b+size+1,change[i][1])-b-1; change[i][2]=upper_bound(b+1,b+size+1,change[i][2])-b-1; } sort(qst+1,qst+m+1,cmp); L=qst[1].l; R=qst[1].r; for (TIM=1;TIM<=qst[1].tim;++TIM) a[change[TIM][0]]=change[TIM][2]; for (i=qst[1].l;i<=qst[1].r;++i) { if (num[a[i]]==0) ans++; num[a[i]]++; } if (qst[1].num) ansi[qst[1].num]=ans; TIM=qst[1].tim; for (i=1;i<=m;++i) work(i); for (i=1;i<=numi;++i) printf("%d\n",ansi[i]); }