【Luogu】P1903数颜色(带修改莫队)
带修改莫队模板。
加一个变量记录现在是第几次修改,看看当前枚举的询问是第几次修改,改少了就改过去,改多了就改回来。
话说我栈用成队列了能过样例?!!!!
从此深信一句话:样例是出题人精心设计的,绞尽脑汁才设计出一个能让错误代码通过的数据qwqqqqq
#include<cstdio> #include<cstdlib> #include<cctype> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #define maxn 50000 using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } int s[maxn]; struct Que{ int x,y,id,dfn; bool operator <(const Que a)const{ if(s[x]!=s[a.x]) return s[x]<s[a.x]; return y<a.y; } }q[maxn],w[maxn]; int cntq,cntw; int cnt; int d[maxn]; int dfn; int sum[maxn]; int stack[maxn],top; int ans[maxn]; int main(){ int n=read(),m=read();int sqt=sqrt(n); for(int i=1;i<=n;++i){ d[i]=read(); s[i]=(i-1)/sqt+1; } for(int i=1;i<=m;++i){ char c[10];int x,y; scanf("%s%d%d",c,&x,&y); if(c[0]=='Q') q[++cntq]=(Que){x,y,cnt,++dfn}; else w[++cntw]=(Que){x,y,++cnt,0}; } sort(q+1,q+cntq+1); int l=0,r=0,now=0,tot=1;sum[0]=1; for(int i=1;i<=cntq;++i){ int x=q[i].x,y=q[i].y,id=q[i].id; while(r<y){ r++; sum[d[r]]++; if(sum[d[r]]==1) tot++; } while(r>y){ sum[d[r]]--; if(sum[d[r]]==0) tot--; r--; } while(l<x){ sum[d[l]]--; if(sum[d[l]]==0) tot--; l++; } while(l>x){ l--; sum[d[l]]++; if(sum[d[l]]==1) tot++; } while(now<id){ stack[++top]=d[w[++now].x]; d[w[now].x]=w[now].y; if(w[now].x>=x&&w[now].x<=y){ sum[stack[top]]--; if(sum[stack[top]]==0) tot--; sum[w[now].y]++; if(sum[w[now].y]==1) tot++; } } while(now>id){ int col=stack[top--]; int old=w[now].y; d[w[now].x]=col; if(w[now].x>=x&&w[now].x<=y){ sum[old]--; if(sum[old]==0) tot--; sum[col]++; if(sum[col]==1) tot++; } now--; } ans[q[i].dfn]=tot; } for(int i=1;i<=dfn;++i) printf("%d\n",ans[i]); return 0; }