zoukankan      html  css  js  c++  java
  • bzoj 2453: 维护队列

    2453: 维护队列

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1079  Solved: 503
    [Submit][Status][Discuss]

    Description

    你小时候玩过弹珠吗?
    小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N。为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少。当然,A有时候会依据个人喜好,替换队列中某个弹珠的颜色。但是A还没有学过编程,且觉得头脑风暴太浪费脑力了,所以向你来寻求帮助。

    Input

    输入文件第一行包含两个整数N和M。
    第二行N个整数,表示初始队列中弹珠的颜色。
    接下来M行,每行的形式为“Q L R”或“R x c”,“Q L R”表示A想知道从队列第L个弹珠到第R个弹珠中,一共有多少不同颜色的弹珠,“R x c”表示A把x位置上的弹珠换成了c颜色。

    Output

    对于每个Q操作,输出一行表示询问结果。

    Sample Input


    2 3
    1 2
    Q 1 2
    R 1 2
    Q 1 2

    Sample Output

    2
    1

    HINT

    对于100%的数据,有1 ≤ N ≤ 10000, 1 ≤ M ≤ 10000,小朋友A不会修改超过1000次,所有颜色均用1到10^6的整数表示。

    Source

    2011福建集训

    带修莫队

    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    #define N 10001
    #define M 1000001
    using namespace std;
    int n,m,col[M],sum[M],ans[N];
    int tot,now,siz,tmp;
    struct     Query
    {
        int l,r,bl,id,tim;
        bool operator <  (Query p) const
        {
            if(bl!=p.bl) return bl<p.bl;
            if(r!=p.r) return r<p.r;
            return tim<p.tim;
        }
    }e[N];
    struct Change
    {
        int be,af,pos;
    }g[1001];
    void update(int p,int w)
    {
        sum[p]+=w;
        if(sum[p]==1 && w==1) tmp++;
        if(!sum[p] && w==-1) tmp--;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        siz=sqrt(n);
        for(int i=1;i<=n;i++) scanf("%d",&col[i]);
        char s[3]; int l,r;
        while(m--)
        {
            scanf("%s%d%d",s,&l,&r);
            if(s[0]=='Q')
            {
                e[++tot].l=l; e[tot].r=r; e[tot].bl=(l-1)/siz; e[tot].tim=now;
                e[tot].id=tot;
            }
            else
            {
                g[++now].pos=l; g[now].af=r;
            }
        }
        sort(e+1,e+tot+1);
        int L=1,R=0; now=0;
        for(int i=1;i<=tot;i++)
        {
            while(now<e[i].tim)
            {
                now++;
                g[now].be=col[g[now].pos];
                if(g[now].pos>=L&&g[now].pos<=R)
                {
                    update(g[now].be,-1);
                    update(g[now].af,1);
                }
                col[g[now].pos]=g[now].af;
            }
            while(now>e[i].tim)
            {
                if(g[now].pos>=L&&g[now].pos<=R)
                {
                    update(g[now].af,-1);
                    update(g[now].be,1);
                }
                col[g[now].pos]=g[now].be;
                now--;
            }
            while(e[i].l<L) update(col[--L],1);
            while(e[i].l>L) update(col[L++],-1);
            while(e[i].r>R) update(col[++R],1);
            while(e[i].r<R) update(col[R--],-1);
            ans[e[i].id]=tmp;
        }
        for(int i=1;i<=tot;i++) printf("%d
    ",ans[i]);
    }

    优化后:

    读入优化、1,-1改成 true,false

    优化一半

    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    #define N 10001
    #define M 1000001
    using namespace std;
    int n,m,col[M],sum[M],ans[N];
    int tot,now,siz,tmp;
    struct     Query
    {
        int l,r,bl,id,tim;
        bool operator <  (Query p) const
        {
            if(bl!=p.bl) return bl<p.bl;
            if(r!=p.r) return r<p.r;
            return tim<p.tim;
        }
    }e[N];
    struct Change
    {
        int be,af,pos;
    }g[1001];
    void update(int p,bool w)
    {
        if(w)
        {
            sum[p]++;
            if(sum[p]==1) tmp++;
        }
        else
        {
            sum[p]--;
            if(!sum[p]) tmp--;
        }
    }
    void read(int &x)
    {
        x=0; char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); }
    }
    int main()
    {
        read(n); read(m);
        siz=sqrt(n);
        for(int i=1;i<=n;i++) read(col[i]);
        char s[3]; int l,r;
        while(m--)
        {
            scanf("%s",s);
            read(l); read(r);
            if(s[0]=='Q')
            {
                e[++tot].l=l; e[tot].r=r; e[tot].bl=(l-1)/siz; e[tot].tim=now;
                e[tot].id=tot;
            }
            else
            {
                g[++now].pos=l; g[now].af=r;
            }
        }
        sort(e+1,e+tot+1);
        int L=1,R=0; now=0;
        for(int i=1;i<=tot;i++)
        {
            while(now<e[i].tim)
            {
                now++;
                g[now].be=col[g[now].pos];
                if(g[now].pos>=L&&g[now].pos<=R)
                {
                    update(g[now].be,false);
                    update(g[now].af,true);
                }
                col[g[now].pos]=g[now].af;
            }
            while(now>e[i].tim)
            {
                if(g[now].pos>=L&&g[now].pos<=R)
                {
                    update(g[now].af,false);
                    update(g[now].be,true);
                }
                col[g[now].pos]=g[now].be;
                now--;
            }
            while(e[i].l<L) update(col[--L],true);
            while(e[i].l>L) update(col[L++],false);
            while(e[i].r>R) update(col[++R],true);
            while(e[i].r<R) update(col[R--],false);
            ans[e[i].id]=tmp;
        }
        for(int i=1;i<=tot;i++) printf("%d
    ",ans[i]);
    }
  • 相关阅读:
    字符串加密
    接口实例
    RecyclerView添加Hearder
    基于Vue实现图片在指定区域内移动
    Tinymce 编辑器添加自定义图片管理插件
    LocalStorage和sessionStorage之间的区别
    javascript之url转义escape()、encodeURI()和decodeURI(),ifram父子传参参数有中文时出现乱码
    Js实现简单的音频播放
    通用CSS命名规范
    Hbuilder常用功能汇总
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7067135.html
Copyright © 2011-2022 走看看