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的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces 620E New Year Tree(线段树的骚操作第二弹)