没错莫队就是这么强!
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define SG string
#define DB double
using namespace std;
const int Max1=1e6+5;
const int Max2=1e4+5;
struct Node1{
int X,Y,Id,Time;
}Ask[Max2];
struct Node2{
int Loc,New,Old;
}Change[Max2];
char CH[2];
int N,M,S,L,R,T,Tot,Ask_Num,Change_Num,A[Max2],B[Max2],Cnt[Max1],Ans[Max1];
bool Cmp(Node1 P,Node1 Q){
return B[P.X]==B[Q.X]?P.Y<Q.Y:B[P.X]<B[Q.X];
}
void Insert(int X){
Cnt[X]++;
if(Cnt[X]==1){
Tot++;
}
}
void Delete(int X){
Cnt[X]--;
if(Cnt[X]==0){
Tot--;
}
}
void Update(int X,int Y){
if(L<=X&&X<=R){
Delete(A[X]);
}A[X]=Y;
if(L<=X&&X<=R){
Insert(A[X]);
}
}
int main(){
int I,J,K;
scanf("%d%d",&N,&M);S=sqrt(N);
for(I=1;I<=N;I++){
scanf("%d",&A[I]);B[I]=I/S;
}
for(I=1;I<=M;I++){
int X,Y;
scanf("%s%d%d",CH,&X,&Y);
if(CH[0]=='Q'){
Ask[++Ask_Num].X=X;Ask[Ask_Num].Y=Y;Ask[Ask_Num].Id=Ask_Num;Ask[Ask_Num].Time=Change_Num;
} else {
Change[++Change_Num].Loc=X;Change[Change_Num].New=Y;Change[Change_Num].Old=A[X];A[X]=Y;
}
}
T=Change_Num;
sort(Ask+1,Ask+1+Ask_Num,Cmp);
for(I=1;I<=Ask_Num;I++){
while(R<Ask[I].Y){
Insert(A[++R]);
}
while(R>Ask[I].Y){
Delete(A[R--]);
}
while(L<Ask[I].X){
Delete(A[L++]);
}
while(L>Ask[I].X){
Insert(A[--L]);
}
while(T>Ask[I].Time){
Update(Change[T].Loc,Change[T].Old);T--;
}
while(T<Ask[I].Time){
T++;Update(Change[T].Loc,Change[T].New);
}
Ans[Ask[I].Id]=Tot;
}
for(I=1;I<=Ask_Num;I++){
printf("%d\n",Ans[I]);
}
return 0;
}