带修改的莫队算法
参考博客:​​【莫队算法】​​ 膜拜大佬

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

const int maxn=10000+100;
struct Moq{

int l,r;
int Time;
int id;
}moq[maxn];
struct Moc{

int ind;
int New;
int Old;
}moc[maxn];

int n,m,color[maxn*110],s[maxn],tmp[maxn],ans[maxn],R[maxn];
int l=1,r,T;
int tot,time;
int Ans;

inline void kaven(int ind,int v){

color[ind]+=v;
if(v>0) Ans+=(color[ind]==1);
if(v<0) Ans-=(color[ind]==0);
}

inline void chang(int ind,int v){

if(ind>=l&&ind<=r){

kaven(v,1);
kaven(s[ind],-1);
}
s[ind]=v;
}

inline bool cmp(Moq a,Moq b){

return R[a.l]==R[b.l]?(R[a.r]==R[b.r]?a.Time<b.Time:a.r<b.r):a.l<b.l;
}

int main(){

scanf("%d%d",&n,&m);
int unit=(int)pow(n,0.666666);
for(int i=1;i<=n;i++) scanf("%d",&s[i]),tmp[i]=s[i],R[i]=i/unit+1;
for(int i=1;i<=m;i++){

char sign;
int x,y;
scanf(" %c%d%d",&sign,&x,&y);
if(sign=='Q'){

moq[++tot].id=tot;
moq[tot].l=x;
moq[tot].r=y;
moq[tot].Time=time;
}
else{

moc[++time].ind=x;
moc[time].New=y;
moc[time].Old=tmp[x];
tmp[x]=y;
}
}
sort(moq+1,moq+tot+1,cmp);
for(int i=1;i<=tot;i++){

while(T<moq[i].Time) chang(moc[T+1].ind,moc[T+1].New),T++;
while(T>moq[i].Time) chang(moc[T].ind,moc[T].Old),T--;

while(l<moq[i].l) kaven(s[l],-1),l++;
while(l>moq[i].l) kaven(s[l-1],1),l--;
while(r<moq[i].r) kaven(s[r+1],1),r++;
while(r>moq[i].r) kaven(s[r],-1),r--;

ans[moq[i].id]=Ans;
}
for(int i=1;i<=tot;i++) printf("%d\n",ans[i]);
}