zoukankan      html  css  js  c++  java
  • CF707D Persistent Bookcase 可持久化线段树

    维护一个二维零一矩阵(n,m<=1000),支持四种操作(不超过10^5次):

    • 将(i,j)置一
    • 将(i,j)置零
    • 将第i行零一反转yu
    • 回到第K次操作前的状态
    • 每次操作后输出全局一共有多少个一

    你发现如果每一次操作都复制一整行的话是可以用 $bitset$ 优化的,自带/32 

    所以,我们对于每一个时刻维护一个线段树,其中 $i$ 节点表示第 $i$ 行对应的 $bitset$ 编号.  

    对于前 $3$ 个操作,每一次操作时都暴力新建一个 bitset,然后每次在可持久化线段树上最多更新一个单点. 

    顺便在线段树的节点上再维护一个 $1$ 的数量即可. 

    #include <bits/stdc++.h>  
    #define M 1004 
    #define N 100005      
    #define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout) 
    using namespace std; 
    bitset<M>v[N],uni,oo;       
    int rt[N]; 
    namespace seg
    {  
        #define lson t[x].ls 
        #define rson t[x].rs  
        int tot; 
        int newnode() { return ++ tot; }    
        struct Node 
        {
            int ls,rs,id,sum;        
        }t[N*40]; 
        int update(int x,int l,int r,int p,int v) 
        {    
            int now=newnode(); 
            t[now]=t[x];           
            if(l==r) 
            {
                t[now].id=v;    
                return now; 
            }
            int mid=(l+r)>>1;   
            if(p<=mid) 
            {
                t[now].ls=update(lson,l,mid,p,v); 
            }
            else 
            {
                t[now].rs=update(rson,mid+1,r,p,v);    
            }
            t[now].sum=t[t[now].ls].sum+t[t[now].rs].sum;   
            return now;    
        }
        int modify(int x,int l,int r,int p,int v) 
        {
            int now=newnode();  
            t[now]=t[x];      
            if(l==r) 
            {
                t[now].sum=v;      
                return now; 
            }
            int mid=(l+r)>>1; 
            if(p<=mid) t[now].ls=modify(lson,l,mid,p,v); 
            else t[now].rs=modify(rson,mid+1,r,p,v); 
            t[now].sum=t[t[now].ls].sum+t[t[now].rs].sum;          
            return now; 
        }
        int query(int x,int l,int r,int p) 
        {
            if(!x) return 0; 
            if(l==r)  return t[x].id; 
            int mid=(l+r)>>1;   
            if(p<=mid) return query(lson,l,mid,p); 
            else return query(rson,mid+1,r,p);   
        }  
        void dfs(int x,int l,int r) 
        {
            if(!x) return;       
            if(l==r) printf("%d %d
    ",l,t[x].sum);   
            int mid=(l+r)>>1;        
            dfs(lson,l,mid), dfs(rson,mid+1,r); 
        }
        #undef lson 
        #undef rson   
    }; 
    int main() 
    { 
        // setIO("now"); 
        int n,m,q,i,j; 
        scanf("%d%d%d",&n,&m,&q);           
        for(i=1;i<=m;++i) uni[i]=1;    
        for(i=1;i<=q;++i) 
        {
            int op,a,b,c; 
            scanf("%d",&op);       
            rt[i]=rt[i-1];      
            if(op==1)
            {  
                scanf("%d%d",&a,&b);           
                int pre=seg::query(rt[i-1],1,n,a);         
                v[i]=v[pre];   
                v[i][b]=1;           
                rt[i]=seg::update(rt[i-1],1,n,a,i);                
                oo=v[i]&uni;     
                rt[i]=seg::modify(rt[i],1,n,a,oo.count());       
            } 
            if(op==2) 
            { 
                scanf("%d%d",&a,&b);   
                int pre=seg::query(rt[i-1],1,n,a);      
                v[i]=v[pre]; 
                v[i][b]=0;                                                               
                rt[i]=seg::update(rt[i-1],1,n,a,i);       
                oo=v[i]&uni;                             
                rt[i]=seg::modify(rt[i],1,n,a,oo.count()); 
            }
            if(op==3) 
            {   
                int x; 
                scanf("%d",&x);    
                int pre=seg::query(rt[i-1],1,n,x);    
                v[i]=v[pre]^uni;     
                rt[i]=seg::update(rt[i-1],1,n,x,i);
                oo=v[i]&uni;        
                rt[i]=seg::modify(rt[i],1,n,x,oo.count());           
            } 
            if(op==4) 
            {
                int x; 
                scanf("%d",&x);    
                rt[i]=rt[x];                
            }
            printf("%d
    ",seg::t[rt[i]].sum);   
        }
        return 0; 
    }
    

      

  • 相关阅读:
    人月神话阅读笔记01
    第二周总结
    第一周总结
    软件工程课程总结
    FIR滤波器窗函数设计法详细步骤以及Matlab代码
    【转载】傅立叶变换、拉普拉斯变换、Z变换之间的联系?
    Matlab实现IIR数字滤波器设计
    数字信号滤波器的重要函数
    奇异谱分析
    字符串解码DecodeString
  • 原文地址:https://www.cnblogs.com/guangheli/p/11720361.html
Copyright © 2011-2022 走看看