Description
墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令: 1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。为了满足墨墨的要求,你知道你需要干什么了吗?
带修改莫队,给每个询问加一个权值时间tim,询问的时候让时光回溯
Code
#include <cstdio> #include <algorithm> #include <cmath> #define N 10010 using namespace std; int n,m,col[N],now[N],bl[N],Tim,cnt,Ans[N],sum,Scol[N*100],l,r; struct change{ int p,v,pre; change(){} change(int a,int b,int c):p(a),v(b),pre(c){} }c[N/10]; struct query{ int tim,l,r,id; query(){} query(int a,int b,int c,int d):l(a),r(b),tim(c),id(d){} friend bool operator <(query a,query b){ return (bl[a.l]==bl[b.l])?(a.r==b.r?a.tim<b.tim:a.r<b.r):a.l<b.l; } }q[N]; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } void upd(int x,int d){ Scol[x]+=d; if(d>0) sum+=(Scol[x]==1); else sum-=(Scol[x]==0); } void go(int x,int d){ if(l<=x&&x<=r) upd(d,1),upd(col[x],-1); col[x]=d; } int main(){ n=read(),m=read();int blo=sqrt(n); for(int i=1;i<=n;++i) col[i]=now[i]=read(),bl[i]=i/blo+1; for(int i=1;i<=m;++i){ char ch;for(ch=getchar();ch!='Q'&&ch!='R';ch=getchar()); int x=read(),y=read(); if(ch=='Q') q[++cnt]=query(x,y,Tim,cnt); else c[++Tim]=change(x,y,now[x]),now[x]=y; } sort(q+1,q+cnt+1); for(int i=1,t=0;i<=cnt;++i){ for(;t<q[i].tim;t++) go(c[t+1].p,c[t+1].v); for(;t>q[i].tim;t--) go(c[t].p,c[t].pre); for(;l<q[i].l;l++) upd(col[l],-1); for(;l>q[i].l;l--) upd(col[l-1],1); for(;r<q[i].r;r++) upd(col[r+1],1); for(;r>q[i].r;r--) upd(col[r],-1); Ans[q[i].id]=sum; } for(int i=1;i<=cnt;printf("%d ",Ans[i++])); return 0; }