Solution
带修莫队模板?
先将所有读入中有的编码离散
每经过一次修改操作,将时间加一
对于每次查询,记录A,B,时间
将时间作为第三个排序元素,跑莫队
Code
#include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> using namespace std; const int N=1e5+10; struct node { int x,id; bool operator <(const node &o)const { return x<o.x; } }a[N*4]; int n,m,d[N],s[N*4],T[N][3],tot,cnt,sc,sq,x,y,k,si,nl,nr,nt,ans[N]; char ss[5]; struct mode { int l,r,t,id,k; bool operator <(const mode &o)const { return l/si==o.l/si?(r/si==o.r/si?t<o.t:r<o.r):l<o.l; } }q[N]; int read() { int sum=0,fh=1; char ch=getchar(); while(!(ch>='0' && ch<='9')) { if(ch=='-') fh=-1; ch=getchar(); } while(ch>='0' && ch<='9' && ch!=EOF) sum=sum*10+ch-48,ch=getchar(); return sum*fh; } int main() { n=read(),m=read(); int once=n+m; for(int i=1;i<=n;i++) { d[i]=read(); a[++tot]=(node){d[i],i+once*3}; } for(int i=1;i<=m;i++) { scanf("%s",ss); scanf("%d%d",&x,&y); if(ss[0]=='C') { if(d[x]==y) continue; T[++sc][0]=x,T[sc][1]=d[x],T[sc][2]=y; a[++tot]=(node){d[x],sc+once},a[++tot]=(node){y,sc+once*2}; d[x]=y; } else if(ss[0]=='Q') { scanf("%d",&k); q[++sq]=(mode){x,y,sc,sq,k}; a[++tot]=(node){k,sq}; } } sort(a+1,a+1+tot); for(int i=1;i<=tot;i++) { if(i==1 || a[i].x!=a[i-1].x) cnt++; x=a[i].id%once,y=a[i].id/once; if(y==0) q[x].k=cnt; else if(y<3) T[x][y]=cnt; else d[x]=cnt; } si=pow(n,0.6666667); sort(q+1,q+1+sq); for(int i=1;i<=sq;i++) { int l=q[i].l,r=q[i].r,t=q[i].t; while(nl<l) s[d[nl++]]--; while(nl>l) s[d[--nl]]++; while(nr<r) s[d[++nr]]++; while(nr>r) s[d[nr--]]--; while(nt<t) { nt++; if(nl<=T[nt][0] && nr>=T[nt][0]) s[T[nt][1]]--,s[T[nt][2]]++; d[T[nt][0]]=T[nt][2]; } while(nt>t) { if(nl<=T[nt][0] && nr>=T[nt][0]) s[T[nt][1]]++,s[T[nt][2]]--; d[T[nt][0]]=T[nt][1]; nt--; } ans[q[i].id]=s[q[i].k]; } for(int i=1;i<=sq;i++) printf("%d\n",ans[i]); return 0; }