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\n",(int)aa.count());     
        }
    }
    return 0; 
}

  

posted @ 2019-10-29 14:34  EM-LGH  阅读(160)  评论(3编辑  收藏  举报