标准的带修莫队。。。咕到了现在$qwq$
莫队是对询问排序来优化复杂度的(不带修就是对询问区间$[l,r]$排序)。。
那么现在带修了,我们再可以维护一个时间维度$tm$:对于每个询问,每次回答前先检查时间指针是否与询问的时间对应,不对应则按操作时间修改。
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<cctype> #include<cstdlib> #include<vector> #include<queue> #include<map> #include<set> #define ull unsigned long long #define ll long long #define R register int #define pause (for(R i=1;i<=10000000000;++i)) #define OUT freopen("out.out","w",stdout); using namespace std; namespace Fread { //static char B[1<<15],*S=B,*D=B; //#define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++) inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } inline bool isempty(const char& ch) {return ch<=36||ch>=127;} inline void gs(char* s) {register char ch; while(isempty(ch=getchar())); do *s++=ch; while(!isempty(ch=getchar()));} }using Fread::g; using Fread::gs; const int M=50010; int n,m,T,tim,cl[M*100],cnt,cntq,a[M],crt[M],pos[M],ans[M],anss,l=1,r=0; struct node { int l,r,tm,rk; inline bool operator <(const node& that) { return pos[l]==pos[that.l]?(pos[r]==pos[that.r]?tm<that.tm:(pos[l]&1)?r<that.r:r>that.r):l<that.l; //return pos[l]==pos[that.l]?(pos[r]==pos[that.r]?tm<that.tm:r<that.r):l<that.l; } #define l(i) s[i].l #define r(i) s[i].r #define tm(i) s[i].tm #define rk(i) s[i].rk }s[M]; struct que{int pos,nw,od;}q[M]; inline void change(int pos,int inc) {inc>0?anss+=(++cl[pos]==1):anss-=(--cl[pos]==0);} inline void upd(int pos,int nw) { if(pos>=l&&pos<=r) change(a[pos],-1),change(nw,1); a[pos]=nw; } signed main() { #ifdef JACK freopen("NOIPAK++.in","r",stdin); #endif n=g(),m=g(); T=pow(n,2.0/3); for(R i=1;i<=n;++i) a[i]=g(); memcpy(crt,a,sizeof(int)*(n+1)); for(R i=1;i<=n;++i) pos[i]=(i-1)/T+1; for(R i=1;i<=m;++i) { register char ch; while(!isalpha(ch=getchar())); R l=g(),r=g(); if(ch=='Q') l(++cnt)=l,r(cnt)=r,tm(cnt)=cntq,rk(cnt)=cnt; else q[++cntq].pos=l,q[cntq].nw=r,q[cntq].od=crt[l],crt[l]=r; } sort(s+1,s+cnt+1); for(R i=1;i<=m;++i) { while(tim<tm(i)) ++tim,upd(q[tim].pos,q[tim].nw); while(tim>tm(i)) upd(q[tim].pos,q[tim].od),--tim; while(l<l(i)) change(a[l],-1),++l; while(l>l(i)) change(a[--l],1); while(r<r(i)) change(a[++r],1); while(r>r(i)) change(a[r],-1),--r; ans[rk(i)]=anss; } for(R i=1;i<=cnt;++i) printf("%d ",ans[i]); }
2019.07.03