带修莫队的题目 找答案可以直接暴力 因为答案是\(O(\sqrt{n})\)级别的 懒得证明了
#include #include #include #include #include using namespace std; int L,R,T,a[200100],b[200100],ans[200100],num_cnt,color[200100],times[200100],sz,belong[200100],n,m,Acnt,Qcnt; map M; struct Query{ int l,r,t,id; bool operator < (const Query & b) const { return (belong[l]==belong[b.l])?(belong[r]==belong[b.r]?t=L&&A[t].pos<=R){ times[color[A[t].before]]--; color[A[t].before]--; times[color[A[t].before]]++; times[color[A[t].after]]--; color[A[t].after]++; times[color[A[t].after]]++; } a[A[t].pos]=A[t].after; } else{ if(A[t].pos>=L&&A[t].pos<=R){ times[color[A[t].after]]--; color[A[t].after]--; times[color[A[t].after]]++; times[color[A[t].before]]--; color[A[t].before]++; times[color[A[t].before]]++; } a[A[t].pos]=A[t].before; } T+=opt; } void moveL(int opt){ if(opt==1){ times[color[a[L]]]--; color[a[L]]--; times[color[a[L]]]++; L++; } else{ L--; times[color[a[L]]]--; color[a[L]]++; times[color[a[L]]]++; } } void moveR(int opt){ if(opt==1){ R++; times[color[a[R]]]--; color[a[R]]++; times[color[a[R]]]++; } else{ times[color[a[R]]]--; color[a[R]]--; times[color[a[R]]]++; R--; } } int main(){ scanf("%d %d",&n,&m); init(); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); if(!M[a[i]]) M[a[i]]=++num_cnt; a[i]=b[i]=M[a[i]]; } for(int i=1;i<=m;i++){ int opt,x,y; scanf("%d %d %d",&opt,&x,&y); if(opt==1){ ++Qcnt; Q[Qcnt].id=Qcnt; Q[Qcnt].l=x; Q[Qcnt].r=y; Q[Qcnt].t=Acnt; } else{ ++Acnt; A[Acnt].pos=x; if(!M[y]) M[y]=++num_cnt; y=M[y]; A[Acnt].before=b[x]; A[Acnt].after=y; b[x]=y; } } sort(Q+1,Q+Qcnt+1); L=1; R=0; T=0; times[0]=num_cnt; for(int i=1;i<=Qcnt;i++){ while(L>Q[i].l) moveL(-1); while(RQ[i].r) moveR(-1); while(TQ[i].t) moveT(T,-1); ans[Q[i].id]=getans(); } for(int i=1;i<=Qcnt;i++) printf("%d\n",ans[i]); return 0; }
Q[i].r) moveR(-1); while(TQ[i].t) moveT(T,-1); ans[Q[i].id]=getans(); } for(int i=1;i<=Qcnt;i++) printf("%d\n",ans[i]); return 0; }
Q[i].t) moveT(T,-1); ans[Q[i].id]=getans(); } for(int i=1;i<=Qcnt;i++) printf("%d\n",ans[i]); return 0; }