2120. [国家集训队]数颜色【带修莫队】
Description
墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令: 1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。为了满足墨墨的要求,你知道你需要干什么了吗?
Input
第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。
Output
对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。
Sample Input
6 5
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6
Sample Output
4
4
3
4
4
3
4
HINT
对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。
莫队模板题
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 #include<algorithm> 6 #define N (50000+100) 7 using namespace std; 8 9 struct Qu{int x,y,t,num,ans;}Q[N]; 10 struct Up{int pre,pos,val;}U[N]; 11 int n,m,a[N],Q_num,U_num,l=1,r=0,Color,now,Keg[N*20],x,y,id[N]; 12 char opt[3]; 13 bool cmp1(Qu a,Qu b){return id[a.x]==id[b.x]?(id[a.y]==id[b.y]?a.t<b.t:id[a.y]<id[b.y]):id[a.x]<id[b.x];} 14 bool cmp2(Qu a,Qu b){return a.num<b.num;} 15 16 void Ins(int x){++Keg[x]; if (Keg[x]==1) Color++;} 17 void Del(int x){--Keg[x]; if (Keg[x]==0) Color--;} 18 19 void Recovery(int pos,int val) 20 { 21 if (pos>=l && pos<=r) Del(a[pos]),Ins(val); 22 a[pos]=val; 23 } 24 25 void MoQueue() 26 { 27 for (int i=1; i<=Q_num; ++i) 28 { 29 while (now<Q[i].t) Recovery(U[now+1].pos,U[now+1].val),now++; 30 while (now>Q[i].t) Recovery(U[now].pos,U[now].pre),now--; 31 while (l<Q[i].x) Del(a[l++]); 32 while (l>Q[i].x) Ins(a[--l]); 33 while (r<Q[i].y) Ins(a[++r]); 34 while (r>Q[i].y) Del(a[r--]); 35 Q[i].ans=Color; 36 } 37 } 38 39 int main() 40 { 41 scanf("%d%d",&n,&m); 42 int unit=pow(n,2.0/3.0); 43 for (int i=1; i<=n; ++i) 44 scanf("%d",&a[i]),id[i]=i/unit; 45 for (int i=1; i<=m; ++i) 46 { 47 scanf("%s%d%d",opt,&x,&y); 48 if (opt[0]=='Q') 49 { 50 Q[++Q_num].x=x; 51 Q[Q_num].y=y; 52 Q[Q_num].t=U_num; 53 Q[Q_num].num=i; 54 } 55 else 56 { 57 U[++U_num].pos=x; 58 U[U_num].pre=a[x]; 59 U[U_num].val=y; 60 a[x]=y; 61 } 62 } 63 for (int i=U_num; i>=1; --i) 64 a[U[i].pos]=U[i].pre; 65 sort(Q+1,Q+Q_num+1,cmp1); 66 MoQueue(); 67 sort(Q+1,Q+Q_num+1,cmp2); 68 for (int i=1; i<=Q_num; ++i) 69 printf("%d\n",Q[i].ans); 70 }