zoukankan      html  css  js  c++  java
  • bzoj2120: 数颜色(BIT套主席树+set/分块)

      带修改的 HH的项链。

      带修改考虑用BIT套主席树,查区间里有几个不同的数用a[i]上次出现的位置pre[i]<l的数有几个来算就好了。

      考虑怎么修改。修改i的时候,我们需要改变i同颜色的后继的pre,加入新的颜色,并且找到i在新颜色中的前驱后继,更改自己的pre和在新颜色中后继的pre,于是用一个set来维护每种颜色的前驱后继就好了。

    #include<iostream> 
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath> 
    #include<algorithm> 
    #include<set> 
    using namespace std;
    const int maxn=500010,inf=1e9;
    struct poi{int sum,lt,rt;}tree[maxn<<2]; 
    int n,m,sz,N,x,delta;
    int a[maxn],b[maxn],q1[maxn],q2[maxn],root[maxn],pos[maxn];
    char ch[maxn][1];
    set<int>s[maxn];
    set<int>::iterator pre,it,last;
    inline void read(int &k)
    {
        int f=1;k=0;char c=getchar();
        while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
        while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar();
        k*=f;
    }
    inline int lowbit(int x){return x&-x;}
    void update(int &x,int l,int r,int cx,int delta)
    {
        tree[++sz]=tree[x];tree[sz].sum+=delta;x=sz;
        if(l==r)return;
        int mid=(l+r)>>1;
        if(cx<=mid)update(tree[x].lt,l,mid,cx,delta);
        else update(tree[x].rt,mid+1,r,cx,delta); 
    }
    int query(int x,int l,int r,int cl,int cr)
    {
        if(cl<=l&&r<=cr)return tree[x].sum;
        int mid=(l+r)>>1,ret=0;
        if(cl<=mid)ret+=query(tree[x].lt,l,mid,cl,cr);
        if(cr>mid)ret+=query(tree[x].rt,mid+1,r,cl,cr);
        return ret;
    }
    int main()
    {
        read(n);read(m);
        for(int i=1;i<=n;i++)read(a[i]),b[++N]=a[i];
        for(int i=1;i<=m;i++)
        {
            scanf("%s",ch[i]);read(q1[i]);read(q2[i]);
            if(ch[i][0]=='R')b[++N]=q2[i];
        }
        sort(b+1,b+1+N);N=unique(b+1,b+1+N)-b-1;
        for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+1+N,a[i])-b;
        for(int i=1;i<=n;i++)
        { 
            for(int j=i;j<=n;j+=lowbit(j))
            update(root[j],0,N,pos[a[i]],1);
            s[a[i]].insert(i);pos[a[i]]=i;
        }
        for(int i=1;i<=N;i++)s[i].insert(0);
        for(int i=1;i<=m;i++)
        {
            if(ch[i][0]=='Q')
            {
                int ans=0;
                for(int j=q1[i]-1;j;j-=lowbit(j))ans-=query(root[j],0,N,0,q1[i]-1);
                for(int j=q2[i];j;j-=lowbit(j))ans+=query(root[j],0,N,0,q1[i]-1);
                printf("%d
    ",ans);
            }
            else
            {
                pre=it=last=s[a[q1[i]]].find(q1[i]);pre--;last++;
                if(last!=s[a[q1[i]]].end())
                {
                    for(int j=*last;j<=n;j+=lowbit(j))update(root[j],0,N,q1[i],-1);
                    for(int j=*last;j<=n;j+=lowbit(j))update(root[j],0,N,*pre,1);
                }
                q2[i]=lower_bound(b+1,b+1+N,q2[i])-b;
                for(int j=q1[i];j<=n;j+=lowbit(j))update(root[j],0,N,*pre,-1);
                s[a[q1[i]]].erase(it);a[q1[i]]=q2[i];s[a[q1[i]]].insert(q1[i]);
                pre=last=s[a[q1[i]]].find(q1[i]);pre--;last++; 
                for(int j=q1[i];j<=n;j+=lowbit(j))update(root[j],0,N,*pre,1);
                if(last!=s[a[q1[i]]].end())
                {
                    for(int j=*last;j<=n;j+=lowbit(j))update(root[j],0,N,*pre,-1);
                    for(int j=*last;j<=n;j+=lowbit(j))update(root[j],0,N,q1[i],1);
                } 
            }
        }
    }
    View Code

      分块的做法等会补...

  • 相关阅读:
    So sad! ,Asphyre Closure
    Asphyre Sphinx is a cross-platform framework for developing 2D/3D video games and interactive business applications
    Mark: admob for delphi xe4 integrated 80% -done!-95% to do more test
    CCBPM新手流程设计教程
    CCBPM 常用API接口说明
    CCBPM H5版本中组织结构集成以及与外部数据源同步介绍
    关于驰骋工作流引擎ccbpm 在工业自动化环境下的应用演示实例
    关于驰骋工作流引擎ccbpm 在工业自动化环境下的 应用演示实例
    CCFlow新版本的自由流程、自定义流程功能说明
    关于驰骋工作流引擎ccbpm对bpmn2.0的支持
  • 原文地址:https://www.cnblogs.com/Sakits/p/7624025.html
Copyright © 2011-2022 走看看