• AC日记——数颜色 bzoj 2120


    2120

    思路:

      带修改的莫队;

      对于离线排序询问的算法,如何修改呢?

      每个询问添加一个修改标记;

      表示当前询问在第几个修改之后;

      然后把修改标记作为第三关键字来排序;

      每次更新端点,先更新时间;

      块的大小为n的2/3次方;

    来,上代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    #define maxn 100050
    
    struct QueryType {
        int l,r,t,id;
    };
    struct QueryType qu[maxn];
    
    struct ChangeType {
        int to,x,h;
    };
    struct ChangeType cha[maxn];
    
    int n,m,size=440,tot,num,ai[maxn],bel[maxn],ti[maxn*10],ans[maxn];
    int now;
    
    bool if_[maxn];
    
    inline void in(int &now)
    {
        char Cget=getchar();now=0;
        while(Cget>'9'||Cget<'0') Cget=getchar();
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
    }
    
    bool cmp(QueryType aa,QueryType bb)
    {
        if(bel[aa.l]==bel[bb.l])
        {
            if(bel[aa.r]==bel[bb.r]) return aa.t<bb.t;
            else return aa.r<bb.r;
        }
        else return aa.l<bb.l;
    }
    
    inline void change(int x)
    {
        if(if_[cha[x].to])
        {
            ti[ai[cha[x].to]]--;
            if(!ti[ai[cha[x].to]]) now--;
        }
        cha[x].h=ai[cha[x].to];
        ai[cha[x].to]=cha[x].x;
        if(if_[cha[x].to])
        {
            if(!ti[ai[cha[x].to]]) now++;
            ti[ai[cha[x].to]]++;
        }
    }
    
    inline void unchange(int x)
    {
        if(if_[cha[x].to])
        {
            ti[ai[cha[x].to]]--;
            if(!ti[ai[cha[x].to]]) now--;
        }
        ai[cha[x].to]=cha[x].h;
        if(if_[cha[x].to])
        {
            if(!ti[ai[cha[x].to]]) now++;
            ti[ai[cha[x].to]]++;
        }
    }
    
    inline void updata(int to,int x)
    {
        int pos=ti[ai[to]];
        ti[ai[to]]+=x;
        if(ti[ai[to]]==0&&pos==1) now--;
        if(ti[ai[to]]==1&&pos==0) now++;
        if(x==1) if_[to]=true;
        else if_[to]=false;
    }
    
    int main()
    {
        in(n),in(m);char ch[4];int l,r,t;
        for(int i=1;i<=n;i++) in(ai[i]),bel[i]=(i-1)/size;
        for(int i=1;i<=m;i++)
        {
            scanf("%s",ch);in(l),in(r);
            if(ch[0]=='Q') qu[++tot].l=l,qu[tot].r=r,qu[tot].t=num,qu[tot].id=tot;
            else cha[++num].to=l,cha[num].x=r;
        }
        sort(qu+1,qu+tot+1,cmp),l=1,r=0,t=0,now=0;
        for(int no=1;no<=tot;no++)
        {
            while(t<qu[no].t) change(++t);
            while(t>qu[no].t) unchange(t--);
            while(r<qu[no].r) updata(++r,1);
            while(r>qu[no].r) updata(r--,-1);
            while(l<qu[no].l) updata(l++,-1);
            while(l>qu[no].l) updata(--l,1);
            ans[qu[no].id]=now;
        }
        for(int i=1;i<=tot;i++) printf("%d
    ",ans[i]);
        fclose(stdin),fclose(stdout);
        return 0;
    }
  • 相关阅读:
    Gulp插件less的使用
    并行与并发的区别
    原生javascript实现异步的7种方式
    原生JS实现bind()函数
    职责链模式
    Nginx如何启用ETag,提高访问速度
    前端性能优化:配置ETag
    迭代器模式
    JS里关于事件的常被考察的知识点:事件流、事件广播、原生JS实现事件代理
    cdn网络加速
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6762736.html
Copyright © 2020-2023  润新知