Codeforces 620E New Year Tree

Posted aemshana

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 620E New Year Tree相关的知识,希望对你有一定的参考价值。

题目大意

你有一棵以1为根的有根树,有n个点,每个节点初始有一个颜色c[i]。

有两种操作:

1 v c 将以v为根的子树中所有点颜色更改为c

2 v 查询以v为根的子树中的节点有多少种不同的颜色

$nle400000,1le cleft[i ight]le60$

题解

没啥技术含量的题。颜色数最多为60,可以用一个long long来按位记录下。

然后就根据DFS序建立线段树,就完事了。

Code

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstring>
  4 #include <cstdio>
  5 using namespace std;
  6 
  7 #define LL long long
  8 
  9 struct edge{int Next,to;};
 10 struct SegTreeNode{LL Value,Lazytag;}SegTree[1600100];
 11 edge G[1000010];
 12 int head[400010],Size[400010],ID[400010],DFN[400010],Data[400010];
 13 int N,M,cnt=2,Index=0;
 14 
 15 template<typename elemType>
 16 inline void Read(elemType &T){
 17     elemType X=0,w=0; char ch=0;
 18     while(!isdigit(ch)) {w|=ch==-;ch=getchar();}
 19     while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
 20     T=(w?-X:X);
 21 }
 22 
 23 inline void Add_Edge(int u,int v){
 24     G[cnt].to=v;
 25     G[cnt].Next=head[u];
 26     head[u]=cnt++;
 27 }
 28 
 29 void DFS(int u,int fa){
 30     DFN[u]=++Index;
 31     ID[Index]=u;
 32     Size[u]=1;
 33     for(int i=head[u];i;i=G[i].Next){
 34         int v=G[i].to;
 35         if(v==fa) continue;
 36         DFS(v,u);
 37         Size[u]+=Size[v];
 38     }
 39     return;
 40 }
 41 
 42 inline void Push_Down(int Root){
 43     if(!SegTree[Root].Lazytag) return;
 44     LL temp=SegTree[Root].Lazytag;
 45     SegTree[Root].Lazytag=0;
 46     SegTree[Root<<1].Lazytag=temp;
 47     SegTree[Root<<1].Value=temp;
 48     SegTree[Root<<1|1].Lazytag=temp;
 49     SegTree[Root<<1|1].Value=temp;
 50     return;
 51 }
 52 
 53 void Build_SegTree(int Root,int L,int R){
 54     if(L==R){
 55         SegTree[Root].Lazytag=0;
 56         SegTree[Root].Value=1LL<<Data[ID[L]];
 57         return;
 58     }
 59     int mid=(L+R)>>1;
 60     Build_SegTree(Root<<1,L,mid);
 61     Build_SegTree(Root<<1|1,mid+1,R);
 62     SegTree[Root].Value=SegTree[Root<<1].Value|SegTree[Root<<1|1].Value;
 63     return;
 64 }
 65 
 66 void Update(int Root,int L,int R,int UL,int UR,LL Val){
 67     if(R<UL || UR<L) return;
 68     if(UL<=L && R<=UR){
 69         SegTree[Root].Lazytag=Val;
 70         SegTree[Root].Value=Val;
 71         return;
 72     }
 73     int mid=(L+R)>>1;
 74     Push_Down(Root);
 75     Update(Root<<1,L,mid,UL,UR,Val);
 76     Update(Root<<1|1,mid+1,R,UL,UR,Val);
 77     SegTree[Root].Value=SegTree[Root<<1].Value|SegTree[Root<<1|1].Value;
 78     return;
 79 }
 80 
 81 LL Query(int Root,int L,int R,int QL,int QR){
 82     if(R<QL || QR<L) return 0;
 83     if(QL<=L && R<=QR) return SegTree[Root].Value;
 84     int mid=(L+R)>>1;
 85     Push_Down(Root);
 86     return Query(Root<<1,L,mid,QL,QR)|Query(Root<<1|1,mid+1,R,QL,QR);
 87 }
 88 
 89 inline int Calc(LL x){
 90     int Res=0;
 91     while(x){
 92         if(x&1) ++Res;
 93         x>>=1;
 94     }
 95     return Res;
 96 }
 97 
 98 int main(){
 99     Read(N);Read(M);
100     for(register int i=1;i<=N;++i)
101         Read(Data[i]);
102     for(register int i=1;i<=N-1;++i){
103         int u,v;
104         Read(u);Read(v);
105         Add_Edge(u,v);
106         Add_Edge(v,u);
107     }
108     DFS(1,0);
109     Build_SegTree(1,1,Index);
110     while(M--){
111         int opt,u,c;
112         Read(opt);
113         if(opt==1){
114             Read(u);Read(c);
115             Update(1,1,Index,DFN[u],DFN[u]+Size[u]-1,(1LL<<c));
116         }
117         else{
118             Read(u);
119             LL Res=Query(1,1,Index,DFN[u],DFN[u]+Size[u]-1);
120             printf("%d
",Calc(Res));
121         }
122     }
123     return 0;
124 }

 

 

以上是关于Codeforces 620E New Year Tree的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces620E New Year Tree

CodeForces 620E New Year Tree(线段树的骚操作第二弹)

Codeforces 620E New Year Tree

codeforces379F New Year Tree

New Year Snowmen CodeForces - 140C

Codeforces 1090C New Year Presents