BZOJ2120: 数颜色
题目描述
题目分析
带修莫队的模板题。
带修莫队时间复杂度看上去很高的样子。。。
是代码呢
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+7;
struct Q{
int l,r,time,id,ans;
inline bool operator <(const Q &rhs)const{return id<rhs.id;}
}q[MAXN];
struct C{
int pos,nw,old;
}c[MAXN];
int n,m,sum[MAXN],ans,belong[MAXN],col[MAXN*10],s[MAXN],l=1,r=0,T,Time,t,now[MAXN];
char opt[2];
inline bool cmp(Q x,Q y){return belong[x.l]==belong[y.l]?(belong[x.r]==belong[y.r]?x.time<y.time:x.r<y.r):x.l<y.l;}
inline void add(int x){col[x]++;if(col[x]==1) ans++;}
inline void del(int x){col[x]--;if(col[x]==0) ans--;}
inline void change(int x,int k){if(l<=x&&x<=r) add(k),del(s[x]);s[x]=k;}
inline int read()
{
int x=0,c=1;
char ch=' ';
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
while(ch=='-')c*=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*c;
}
int main()
{
n=read();m=read();
int S=pow(n,0.66666666);
for(int i=1;i<=n;i++) now[i]=s[i]=read(),belong[i]=(i-1)/S+1;
for(int i=1;i<=m;i++) {
scanf("%s",opt);
int x=read(),y=read();
if(opt[0]=='Q') q[++t]=(Q){x,y,T,t};
else c[++T]=(C){x,y,now[x]},now[x]=y;
}
sort(q+1,q+t+1,cmp);
for(int i=1;i<=t;i++){
while(Time<q[i].time) change(c[Time+1].pos,c[Time+1].nw),Time++;
while(Time>q[i].time) change(c[Time].pos,c[Time].old),Time--;
while(l<q[i].l) del(s[l]),l++;
while(l>q[i].l) add(s[l-1]),l--;
while(r<q[i].r) add(s[r+1]),r++;
while(r>q[i].r) del(s[r]),r--;
q[i].ans=ans;
}
sort(q+1,q+t+1);
for(int i=1;i<=t;i++) printf("%d
",q[i].ans);
}