[Codeforces Round #447][Codeforces 894C]Marco and GCD Sequence
[Educational Codeforces Round 6][Codeforces 620C]Pearls in a Row

[Educational Codeforces Round 6][Codeforces 620E]New Year Tree

Zarxdy34 posted @ 2017年11月22日 12:20 in Codeforces with tags DFS序 线段树 , 706 阅读

    题意:给出一棵以1为根的树,每个节点有一个颜色,颜色数<=60。有两种操作,操作1为将一棵以v为根的子树中的所有节点颜色变为\(a_i\),操作2为查询以v为根的子树中的所有节点有多少种不同颜色。

    题解:考虑到颜色最多只有60种,所以可以用一个long long按位来记录颜色是否出现。对整棵树做出DFS序,然后建线段树,然后就是区间查询区间修改就好了。

 

#include <bits/stdc++.h>
using namespace std;
const int maxn=7e5+10;

struct Segment_Tree
{
	#define ls (o<<1)
	#define rs ((o<<1)|1)
	#define mid ((l+r)>>1)
	int tag[maxn<<1];
	long long v[maxn<<1];

	void Update(int o)
	{
		v[o]=v[ls]|v[rs];
	}

	void Mark_Same(int o,int tg)
	{
		v[o]=1ll<<(tg-1);
		tag[o]=tg;
	}
	
	void Push_Down(int o)
	{
		if (!tag[o]) return;
		Mark_Same(ls,tag[o]);
		Mark_Same(rs,tag[o]);
		tag[o]=0;
	}

	void Change(int o,int l,int r,int a,int b,int tg)
	{
		if (a<=l && r<=b)
		{
			Mark_Same(o,tg);
			return;
		}
		Push_Down(o);
		if (a<=mid) Change(ls,l,mid,a,b,tg);
		if (b> mid) Change(rs,mid+1,r,a,b,tg);
		Update(o);
	}

	long long Query(int o,int l,int r,int a,int b)
	{
		if (a<=l && r<=b)
			return v[o];
		Push_Down(o);
		long long res=0;
		if (a<=mid) res|=Query(ls,l,mid,a,b);
		if (b> mid) res|=Query(rs,mid+1,r,a,b);
		Update(o);
		return res;
	}

	void Build(int o,int l,int r,int *cor)
	{
		if (l==r)
		{
			v[o]=1ll<<(cor[l]-1);
			return;
		}
		Build(ls,l,mid,cor);
		Build(rs,mid+1,r,cor);
		Update(o);
	}
}T;

int head[maxn],nxt[maxn<<1],E[maxn<<1],Ecnt;
int dfsq[maxn],tmp[maxn];
int l[maxn],r[maxn],Index;
int cor[maxn];
int n,m;

void Add_Edge(int x,int y) {nxt[++Ecnt]=head[x];head[x]=Ecnt;E[Ecnt]=y;nxt[++Ecnt]=head[y];head[y]=Ecnt;E[Ecnt]=x;}

void DFS(int x,int father=0)
{
	l[x]=++Index;
	dfsq[Index]=x;
	for (int i=head[x];i;i=nxt[i]) if (E[i]!=father)
		DFS(E[i],x);
	r[x]=Index;
}

int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++) scanf("%d",&cor[i]);
	for (int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),Add_Edge(x,y);
	DFS(1);
	for (int i=1;i<=n;i++) tmp[i]=cor[dfsq[i]];
	T.Build(1,1,n,tmp);
	while (m--)
	{
		int t,v,c;
		scanf("%d",&t);
		if (t==1)
		{
			scanf("%d%d",&v,&c);
			T.Change(1,1,n,l[v],r[v],c);
		}
		else
		{
			scanf("%d",&v);
			long long res=T.Query(1,1,n,l[v],r[v]);
			int ans=0;
			while (res)
			{
				ans+=res%2;
				res>>=1;
			}
			printf("%d\n",ans);
		}
	}
	return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter