zoukankan      html  css  js  c++  java
  • Codeforces Round #368 (Div. 2) D. Persistent Bookcase

    D - Persistent Bookcase

    题目大意:有三种操作,第一种操作,在i 个书架,j个位置放一本书,第二种操作,取下第i个书架,j 个位置的书,第三种操作,

    把第i个书架所有没有书的位置放上书,有书的位置拿掉数,第四种操作,回到第k个操作,问你每次操作后书的总数。

    两种方法:1、离线之后,建树,对于op不等于4的操作i,建一条i-1 到 i的边,对于op==4的造作i,建一条k 到 i的边,书上跑一遍dfs

    得出答案,回溯的时候恢复状态。

    2、无脑主席树,需要注意的是要用bitset优化一下空间,不然会爆炸。。。。

    离线

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define pb push_back
    #define mk make_pair
    #define pii pair<int,int>
    #define read(x) scanf("%d",&x)
    #define lread(x) scanf("%lld",&x)
    
    using namespace std;
    
    typedef long long ll;
    const int N=2e3+7;
    const int M=1e5+7;
    const int inf=0x3f3f3f3f;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    
    struct node
    {
        int op,r,c;
    }qus[M<<1];
    int n,m,q,all,ans[M],sum[N],cnt[N][N],pos[M];
    bool flag[N];
    vector<int> e[M];
    void change(int x)
    {
        int op=qus[x].op;
        int r=qus[x].r,c=qus[x].c;
        if(op==1)
        {
            if(flag[r] && cnt[r][c]==1)
                all++,sum[r]++,cnt[r][c]=0;
            else if(!flag[r] && !cnt[r][c])
                all++,sum[r]++,cnt[r][c]=1;
        }
        else if(op==2)
        {
            if(flag[r] && !cnt[r][c])
                all--,sum[r]--,cnt[r][c]=1;
            else if(!flag[r] && cnt[r][c]==1)
                all--,sum[r]--,cnt[r][c]=0;
        }
        else if(op==3)
        {
            int pre=sum[r];
            sum[r]=m-sum[r];
            all+=sum[r]-pre;
            flag[r]=!flag[r];
        }
    }
    void dfs(int u)
    {
        bool flag=true;
        int p=all;
        if(u!=0)
            change(u);
        if((qus[u].op==1 || qus[u].op==2) && all==p)
            flag=false;
        ans[u]=all;
        for(int v:e[u]) dfs(v);
        if(u!=0 && flag)
            change(u+q);
    }
    int main()
    {
        memset(pos,-1,sizeof(pos));
        read(n); read(m); read(q);
        for(int i=1;i<=q;i++)
        {
            int op,r,c=0;
            read(op); read(r);
            if(op-3<0) read(c);
            qus[i]={op,r,c};
            if(op==1)
                qus[i+q]={2,r,c};
            else if(op==2)
                qus[i+q]={1,r,c};
            else if(op==3)
                qus[i+q]={3,r,c};
            else
                qus[i+q]={4,r,c};
            if(qus[i].op!=4)
                e[i-1].push_back(i);
            else
                e[r].push_back(i);
        }
        dfs(0);
        for(int i=1;i<=q;i++)
            printf("%d
    ",ans[i]);
        return 0;
    }
    /*
    */
    View Code

    在线主席树

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define pb push_back
    #define mk make_pair
    #define pii pair<int,int>
    #define read(x) scanf("%d",&x)
    #define lread(x) scanf("%lld",&x)
    
    using namespace std;
    
    typedef long long ll;
    const int N=1e3+1;
    const int M=1e5+1;
    const int inf=0x3f3f3f3f;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    
    int n,m,q;
    struct seg_tree
    {
        int tot,root[M];
        struct node
        {
            bitset<1005> b;
            bool filp;
            int sum,l,r;
        }a[M*20];
        void up(int x,int l,int r){
            a[x].sum=a[l].sum+a[r].sum;
        }
        void updata(int l,int r,int &x,int y,int pos,int num,int op)
        {
            a[++tot]=a[y]; x=tot;
            if(l==r)
            {
                if(op==1)
                {
                    if(!a[x].filp && !a[x].b[num])
                        a[x].b[num]=true,a[x].sum++;
                    else if(a[x].filp && a[x].b[num])
                        a[x].b[num]=false,a[x].sum++;
                }
                else if(op==2)
                {
                    if(!a[x].filp && a[x].b[num])
                        a[x].b[num]=false,a[x].sum--;
                    else if(a[x].filp && !a[x].b[num])
                        a[x].b[num]=true,a[x].sum--;
                }
                else if(op==3)
                {
                    a[x].sum=m-a[x].sum;
                    a[x].filp=!a[x].filp;
                }
                return;
            }
            int mid=(l+r)>>1;
            if(pos<=mid)
                updata(l,mid,a[x].l,a[y].l,pos,num,op);
            else
                updata(mid+1,r,a[x].r,a[y].r,pos,num,op);
            up(x,a[x].l,a[x].r);
        }
    }seg;
    int main()
    {
        read(n); read(m); read(q);
        for(int i=1;i<=q;i++)
        {
            int op,r,c=0;
            read(op); read(r);
            if(op<=2) read(c);
            if(op!=4)
                seg.updata(1,n,seg.root[i],seg.root[i-1],r,c,op);
            else
                seg.updata(1,n,seg.root[i],seg.root[r],r,c,op);
            printf("%d
    ",seg.a[seg.root[i]].sum);
        }
        return 0;
    }
    /*
    */
    View Code
  • 相关阅读:
    activemq 高可用集群部署
    rabbitmq单机部署、集群部署、haproxy+keepalived 的高可用负载均衡环境搭建
    redis 单机部署、集群部署(主从同步+哨兵)
    zookeeper 单机部署、伪集群部署、集群部署
    IDEA 中调试 dubbo 出现 <dubbo:reference interface="" /> interface not allow null! 异常
    centos 安装 subversion1.8及更高版本
    mysql 两主一从环境搭建
    mysql 一主多从环境搭建
    springboot + post 中文乱码
    android:inputType参数类型说明
  • 原文地址:https://www.cnblogs.com/CJLHY/p/8461929.html
Copyright © 2011-2022 走看看