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;
}
posted @ 2018-05-25 19:08  XSamsara  阅读(140)  评论(0编辑  收藏  举报