题目描述
墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会向你发布如下指令:
1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。
2、 R P Col 把第P支画笔替换为颜色Col。
为了满足墨墨的要求,你知道你需要干什么了吗?
输入输出格式
输入格式:
第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。
第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。
第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。
输出格式:
对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。
思路:
带修莫队裸题
和正常莫队相比,多了一维时间
我们可以把时间当作修改
在莫队的排序时作为第三关键字
在左右端点都处理好后,看时间戳
如果需要修改就修改
当然,我们要提前与处理操作
添加反向操作
便于回滚
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define rii register int i #define rij register int j using namespace std; struct que{ int l,r,t,ans; }x[50005]; struct change{ int wz,color,t; }y[50005][2]; int a[50005],n,m,sum[1000005],nl,nr,nt,ans,cnt,sy[50005],bnt; bool cmp1(que lk,que kl) { if(sy[lk.l]==sy[kl.l]) { if(sy[lk.r]==sy[kl.r]) { return lk.t<kl.t; } return sy[lk.r]<sy[kl.r]; } return sy[lk.l]<sy[kl.l]; } bool cmp2(que lk,que kl) { return lk.t<kl.t; } void ycl() { int b[50005]; for(rii=1;i<=n;i++) { b[i]=a[i]; } for(rii=1;i<=bnt;i++) { y[i][1].wz=y[i][0].wz; y[i][1].color=b[y[i][0].wz]; y[i][1].t=y[i][0].t-1; b[y[i][0].wz]=y[i][0].color; } } void change(int wz,int val) { sum[a[wz]]+=val; if(val==1&&sum[a[wz]]==1) { ans++; } if(val==-1&&sum[a[wz]]==0) { ans--; } } int main() { // freopen("1.in","r",stdin); // freopen("1.out","w",stdout); scanf("%d%d",&n,&m); int len=pow(n,(2.0/3)); for(rii=1;i<=n;i++) { scanf("%d ",&a[i]); sy[i]=i/len+1; } for(rii=1;i<=m;i++) { char c; int ltt,kkk; scanf("%c%d%d ",&c,<t,&kkk); if(c=='Q') { cnt++; x[cnt].l=ltt,x[cnt].r=kkk; x[cnt].t=i; } else { bnt++; y[bnt][0].wz=ltt; y[bnt][0].color=kkk; y[bnt][0].t=i; } } y[bnt+1][0].t=2147483647; y[bnt-1][1].t=-1; ycl(); sort(x+1,x+cnt+1,cmp1); nl=1,nr=1,ans=1,sum[a[1]]=1; int bh=0; for(rii=1;i<=cnt;i++) { while(nl<x[i].l) { change(nl,-1); nl++; } while(nl>x[i].l) { change(nl-1,1); nl--; } while(nr<x[i].r) { change(nr+1,1); nr++; } while(nr>x[i].r) { change(nr,-1); nr--; } int pd=0; while(nt<x[i].t) { if(pd==0) { pd++; bh--; if(y[bh+1][0].t<nt) { bh++; } } if(y[bh+1][0].t>x[i].t) { break; } bh++; if(y[bh][0].wz>=nl&&y[bh][0].wz<=nr) { sum[a[y[bh][0].wz]]--; if(sum[a[y[bh][0].wz]]==0) { ans--; } sum[y[bh][0].color]++; if(sum[y[bh][0].color]==1) { ans++; } } a[y[bh][0].wz]=y[bh][0].color; nt=y[bh][0].t; } pd=0; while(nt>=x[i].t) { if(pd==0) { pd=1; bh++; if(y[bh-1][1].t>=nt) { bh--; } } if(y[bh-1][1].t<x[i].t) { break; } bh--; if(y[bh][1].wz>=nl&&y[bh][1].wz<=nr) { sum[a[y[bh][1].wz]]--; sum[y[bh][1].color]++; if(sum[a[y[bh][1].wz]]==0) { ans--; } if(sum[y[bh][1].color]==1) { ans++; } } a[y[bh][1].wz]=y[bh][1].color; nt=y[bh][1].t; } x[i].ans=ans; } sort(x+1,x+cnt+1,cmp2); for(rii=1;i<=cnt;i++) { printf("%d ",x[i].ans); } }