• [bzoj2120] [洛谷P1903] 数颜色


    Description###

    墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令: 1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。为了满足墨墨的要求,你知道你需要干什么了吗?

    Input###

    第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。

    Output###

    对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。

    Sample Input###

    6 5

    1 2 3 4 5 5

    Q 1 4

    Q 2 6

    R 1 2

    Q 1 4

    Q 2 6

    Sample Output###

    4

    4

    3

    4

    HINT###

    对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。


    想法##

    带修改莫队。
    与普通莫队其实一个意思,就是多了一个tim表示在这个询问操作时已进行了几次修改。
    进行一些修改操作使当前状态与这个询问时原本的状态相同。


    代码##

    注意细节!!!

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    
    using namespace std;
    
    const int N = 10005;
    
    int block;
    int bl(int x) { return (x-1)/block+1; }
    
    int cnt1,cnt2;
    struct ask{
        int l,r,id,tim;
        bool operator < (const ask &b) const{
            return bl(l)<bl(b.l) || (bl(l)==bl(b.l) && r<b.r);     
        }
    }q[N];
    struct cg{
        int x,fr,to;       
    }d[N];
    
    int a[N],cnt[1000005];
    int cur,L,R;
    void add(int x){
        cnt[a[x]]++;
        if(cnt[a[x]]==1) cur++;
    }
    void del(int x){
        cnt[a[x]]--;
        if(cnt[a[x]]==0) cur--;     
    }
    
    void cg_add(int x){
        int id=d[x].x;
        if(L<=id && id<=R){ // 注意是id(即d[x].x)啊,并不是x
            del(id);
            a[id]=d[x].to;
            add(id);
        }
        else a[id]=d[x].to;
    }
    void cg_del(int x){
        int id=d[x].x;
        if(L<=id && id<=R){
            del(id);
            a[id]=d[x].fr;
            add(id);
        }
        else a[id]=d[x].fr;     
    }
    
    int n,m;
    int ans[N];
    
    int main()
    {
        char opt[1];
        int x,y;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=m;i++){
            scanf("%s",opt);
            scanf("%d%d",&x,&y);
            if(opt[0]=='Q'){
                cnt1++;
                q[cnt1]=(ask){x,y,cnt1,cnt2}; 
            }
            else{
                cnt2++;
                d[cnt2]=(cg){x,a[x],y};
                a[x]=y;
            }
        }
        block=sqrt(n);
        sort(q+1,q+cnt1+1);
        
        int t=cnt2;
        L=R=1;
        cnt[a[1]]++; cur=1;
        for(int i=1;i<=cnt1;i++){
            while(R<q[i].r) add(++R);
            while(L>q[i].l) add(--L);
            while(R>q[i].r) del(R--);
            while(L<q[i].l) del(L++);
            while(t>q[i].tim) cg_del(t--); //注意顺序!!
            while(t<q[i].tim) cg_add(++t);
            ans[q[i].id]=cur;
        }
        for(int i=1;i<=cnt1;i++) printf("%d
    ",ans[i]);
        
        return 0;    
    }
    
    既然选择了远方,便只顾风雨兼程
  • 相关阅读:
    POJ
    POJ
    hdu 1569 &1565 (二分图带权最大独立集
    ZOJ
    POJ
    python-socket作业
    ACM-ICPC 2018 焦作赛区网络预赛 F. Modular Production Line (区间K覆盖-最小费用流)
    ACM-ICPC 2018 焦作赛区网络预赛 E. Jiu Yuan Wants to Eat (树链剖分-线性变换线段树)
    POJ 2987
    ACM-ICPC 2018 南京赛区网络预赛 G. Lpl and Energy-saving Lamps (弱线段树)
  • 原文地址:https://www.cnblogs.com/lindalee/p/8481390.html
Copyright © 2020-2023  润新知