题意:有两种操作:
1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。
2、 R P Col 把第P支画笔替换为颜色Col。
对每个1操作 输出答案;
带修莫队 模板题 (加多个T指针) 多注意细节
#include<bits/stdc++.h> #define LL long long #define ULL unsigned long long #define rep(i,j,k) for(int i=j;i<=k;i++) #define dep(i,j,k) for(int i=k;i>=j;i--) #define INF 0x3f3f3f3f #define mem(i,j) memset(i,0,sizeof(i)) #define make(i,j) make_pair(i,j) using namespace std; int a[500005],pos[500005],num[1000005],ans[500005],tmp,l=1,r=0; int now[500005]; struct noqu { int l,r,id,t; }q[500005]; struct noch { int x,old,ne; }c[500005]; bool cmp(noqu a,noqu b) { if(pos[a.l]==pos[b.l]) { if(pos[a.r]==pos[b.r]) { return a.t<b.t; } return pos[a.r]<pos[b.r]; } return pos[a.l]<pos[b.l]; } void rever(int x,int d) { num[x]+=d; if(d>0&&num[x]==1) tmp++; else if(d<0 && num[x]==0) tmp--; } void init(int x,int ne) { if(l<=x && x<=r) { rever(ne,1); rever(a[x],-1); } a[x]=ne; } char s[5]; int x,y; int main() { int n,m; scanf("%d %d",&n,&m); int N=floor(pow(n,0.666666)); rep(i,1,n) { scanf("%d",&a[i]); now[i]=a[i]; pos[i]=(i-1)/N; } int head=0,tail=0; rep(i,1,m) { scanf("%s",s); scanf("%d%d",&x,&y); if(s[0]=='Q') { q[++head]=(noqu){x,y,head,tail}; } else { c[++tail]=(noch){x,now[x],y}; now[x]=y; } } sort(q+1,q+1+head,cmp); int T=0; rep(i,1,head) { while(T<q[i].t) { ++T; init(c[T].x,c[T].ne); } while(T>q[i].t) {init(c[T].x,c[T].old); --T;} while(l<q[i].l) rever(a[l++],-1); while(l>q[i].l) rever(a[--l],1); while(r<q[i].r) rever(a[++r],1); while(r>q[i].r) rever(a[r--],-1); ans[q[i].id]=tmp; } rep(i,1,head) printf("%d\n",ans[i]); return 0; }