BZOJ 2120: 数颜色【带修改莫队】
2120: 数颜色
【题目描述】
传送门
【题解】
带修改莫队模板题。
代码如下
我的写法跟他们的不同,感觉有问题,但是就是过了,我也不知道为什么。
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,a[50005],QL,CL,U;
int hsh[2*50005],Len,Ans,Num[1000005];
int L=1,R=0,hed=0;
struct Ask{
int L,R,T,Ans;
bool operator <(const Ask b)const{return (L/U<b.L/U)||(L/U==b.L/U&&R<b.R);}
}Q[50005];
bool cmp(Ask x,Ask y){return x.T<y.T;}
struct CHG{
int x,p,T;
bool operator <(const CHG b)const{return T<b.T;}
}C[50005];
int read(){
int ret=0;char ch=getchar();bool f=1;
for(;!isdigit(ch);ch=getchar()) f^=!(ch^'-');
for(; isdigit(ch);ch=getchar()) ret=(ret<<3)+(ret<<1)+ch-48;
return f?ret:-ret;
}
void Del(int x){int Now=a[x];Num[Now]--;if(!Num[Now]) Ans--;}
void Add(int x){int Now=a[x];if(!Num[Now]) Ans++;Num[Now]++;}
void Change(int x,int &p){
if(L<=x&&x<=R) Del(x);
int t=a[x];a[x]=p;p=t;
if(L<=x&&x<=R) Add(x);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("prob.in","r",stdin);
freopen("prob.out","w",stdout);
#endif
n=read(),m=read();U=sqrt(n);Len=n;
for(int i=1;i<=n;i++) hsh[i]=a[i]=read();
for(int i=1;i<=m;i++){
char ch[10];scanf("%s",ch);//这是个坑
if(ch[0]=='Q') Q[++QL].L=read(),Q[QL].R=read(),Q[QL].T=i;
else C[++CL].x=read(),C[CL].p=read(),C[CL].T=i;
}
sort(Q+1,Q+1+QL);
for(int i=1;i<=QL;i++){
while(C[hed+1].T<Q[i].T&&hed<CL) ++hed,Change(C[hed].x,C[hed].p);
while(C[hed].T>Q[i].T&&hed) Change(C[hed].x,C[hed].p),hed--;
while(L<Q[i].L) Del(L++);
while(L>Q[i].L) Add(--L);
while(R<Q[i].R) Add(++R);
while(R>Q[i].R) Del(R--);
Q[i].Ans=Ans;
}
sort(Q+1,Q+1+QL,cmp);
for(int i=1;i<=QL;i++) printf("%d\n",Q[i].Ans);
return 0;
}