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; }