【Luogu】P1903数颜色(带修改莫队)

  题目链接

  带修改莫队模板。

  加一个变量记录现在是第几次修改,看看当前枚举的询问是第几次修改,改少了就改过去,改多了就改回来。

  话说我栈用成队列了能过样例?!!!!

  从此深信一句话:样例是出题人精心设计的,绞尽脑汁才设计出一个能让错误代码通过的数据qwqqqqq

#include<cstdio>
#include<cstdlib>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define maxn 50000
using namespace std;
inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-'0';
        ch=getchar();
    }
    return num*f;
}

int s[maxn];
struct Que{
    int x,y,id,dfn;
    bool operator <(const Que a)const{
        if(s[x]!=s[a.x])    return s[x]<s[a.x];
        return y<a.y;
    }
}q[maxn],w[maxn];
int cntq,cntw;
int cnt;
int d[maxn];
int dfn;

int sum[maxn];
int stack[maxn],top;
int ans[maxn];

int main(){
    int n=read(),m=read();int sqt=sqrt(n);
    for(int i=1;i<=n;++i){
        d[i]=read();
        s[i]=(i-1)/sqt+1;
    }
    for(int i=1;i<=m;++i){
        char c[10];int x,y;
        scanf("%s%d%d",c,&x,&y);
        if(c[0]=='Q')    q[++cntq]=(Que){x,y,cnt,++dfn};
        else            w[++cntw]=(Que){x,y,++cnt,0};
    }
    sort(q+1,q+cntq+1);
    int l=0,r=0,now=0,tot=1;sum[0]=1;
    for(int i=1;i<=cntq;++i){
        int x=q[i].x,y=q[i].y,id=q[i].id;
        while(r<y){
            r++;
            sum[d[r]]++;
            if(sum[d[r]]==1)    tot++;
        }
        while(r>y){
            sum[d[r]]--;
            if(sum[d[r]]==0)    tot--;
            r--;
        }
        while(l<x){
            sum[d[l]]--;
            if(sum[d[l]]==0)    tot--;
            l++;
        }
        while(l>x){
            l--;
            sum[d[l]]++;
            if(sum[d[l]]==1)    tot++;
        }
        while(now<id){
            stack[++top]=d[w[++now].x];
            d[w[now].x]=w[now].y;
            if(w[now].x>=x&&w[now].x<=y){
                sum[stack[top]]--;
                if(sum[stack[top]]==0)    tot--;
                sum[w[now].y]++;
                if(sum[w[now].y]==1)    tot++;
            }
        }
        while(now>id){
            int col=stack[top--];
            int old=w[now].y;
            d[w[now].x]=col;
            if(w[now].x>=x&&w[now].x<=y){
                sum[old]--;
                if(sum[old]==0)    tot--;
                sum[col]++;
                if(sum[col]==1)    tot++;
            }
            now--;
        }
        ans[q[i].dfn]=tot;
    }
    for(int i=1;i<=dfn;++i)    printf("%d\n",ans[i]);
    return 0;
}

 

posted @ 2018-01-19 20:01  Konoset  阅读(143)  评论(0编辑  收藏  举报