• CF620E New Year Tree 线段树+dfs序+bitset


    线段树维护 dfs 序是显然的. 

    暴力建 60 个线段树太慢,于是用 bitset 优化就好了 ~

    code: 

    #include <bits/stdc++.h>  
    #define M 63      
    #define N 800005    
    #define lson now<<1 
    #define rson now<<1|1    
    using namespace std;         
    inline void setIO(string s) 
    {
        string in=s+".in"; 
        string out=s+".out"; 
        freopen(in.c_str(),"r",stdin);  
        freopen(out.c_str(),"w",stdout);   
    }
    namespace IO 
    { 
        char *p1,*p2,buf[100000];
        #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
        int rd() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;}
    }; 
    int tot,edges; 
    int dfn[N],size[N],st[N],ed[N],hd[N],to[N<<1],nex[N<<1],val[N];         
    bitset<M>a[M],aa,a0;           
    struct node 
    {   
        bitset<M>v;      
        int tag; 
    }t[N<<2];   
    void add(int u,int v) 
    {
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;   
    }
    void mark(int now,int v) 
    {
        t[now].v=a[v];  
        t[now].tag=v;           
    }
    void pushdown(int l,int r,int now) 
    {
        int mid=(l+r)>>1; 
        if(t[now].tag) 
        {
            mark(lson,t[now].tag);  
            if(r>mid) mark(rson,t[now].tag);   
            t[now].tag=0;                 
        }
    }
    void pushup(int l,int r,int now) 
    {
        int mid=(l+r)>>1;  
        t[now].v=t[lson].v;  
        if(r>mid) t[now].v|=t[rson].v;  
    }   
    void update(int l,int r,int now,int L,int R,int v) 
    {
        if(l>=L&&r<=R) 
        {
            mark(now,v);        
            return;   
        }
        pushdown(l,r,now);   
        int mid=(l+r)>>1;   
        if(L<=mid) update(l,mid,lson,L,R,v);  
        if(R>mid)  update(mid+1,r,rson,L,R,v);   
        pushup(l,r,now);   
    }
    void query(int l,int r,int now,int L,int R) 
    {
        if(l>=L&&r<=R) 
        {
            aa|=t[now].v;         
            return;  
        }
        pushdown(l,r,now);   
        int mid=(l+r)>>1;   
        if(L<=mid) query(l,mid,lson,L,R); 
        if(R>mid)  query(mid+1,r,rson,L,R);     
    }
    void dfs(int u,int ff) 
    { 
        size[u]=1;   
        st[u]=dfn[u]=++tot; 
        for(int i=hd[u];i;i=nex[i]) 
        { 
            int v=to[i]; 
            if(v==ff) continue;       
            dfs(v,u);  
            size[u]+=size[v];  
        } 
        ed[u]=tot;    
    }
    int main() 
    {
        // setIO("data-structure"); 
        int i,j,n,m;    
        n=IO::rd();
        m=IO::rd();    
        // scanf("%d%d",&n,&m);        
        for(i=1;i<=61;++i) a[i][i]=1;                
        for(i=1;i<=n;++i) val[i]=IO::rd();    
        for(i=1;i<n;++i) 
        {
            int u=IO::rd(),v=IO::rd();         
            // scanf("%d%d",&u,&v); 
            add(u,v),add(v,u);   
        }    
        dfs(1,0);              
        for(i=1;i<=n;++i) update(1,n,1,st[i],st[i],val[i]);    
        for(i=1;i<=m;++i) 
        {
            int opt=IO::rd(),x=IO::rd(),y;        
            if(opt==1) 
            {
                y=IO::rd();    
                update(1,n,1,st[x],ed[x],y);  
            }
            else 
            {
                aa=a0; 
                query(1,n,1,st[x],ed[x]);         
                printf("%d
    ",(int)aa.count());     
            }
        }
        return 0; 
    }
    

      

  • 相关阅读:
    bzoj 1031: [JSOI2007]字符加密Cipher
    python re模块实现计算器
    python sys模块和序列化模块
    python time时间模块
    python 发红包的小程序
    python ranndom模块及生成验证码
    python os模块练习题
    python os模块常用命令
    快速排序,归并排序
    选择排序和插入排序
  • 原文地址:https://www.cnblogs.com/guangheli/p/11758581.html
Copyright © 2020-2023  润新知