1. 程式人生 > >【Educational Codeforces Round 6E】【線段樹 dfs序】New Year Tree 子樹顏色修改子樹顏色數

【Educational Codeforces Round 6E】【線段樹 dfs序】New Year Tree 子樹顏色修改子樹顏色數

E. New Year Tree time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output

The New Year holidays are over, but Resha doesn't want to throw away the New Year tree. He invited his best friends Kerim and Gural to help him to redecorate the New Year tree.

The New Year tree is an undirected tree withnvertices and root in the vertex1.

You should process the queries of the two types:

  1. Change the colours of all vertices in the subtree of the vertexvto the colourc.
  2. Find the number of different colours in the subtree of the vertexv.
Input

The first line contains two integersn, m(1 ≤ n, m ≤ 4·105) — the number of vertices in the tree and the number of the queries.

The second line containsn

integersci(1 ≤ ci ≤ 60) — the colour of thei-th vertex.

Each of the nextn - 1lines contains two integersxj, yj(1 ≤ xj, yj ≤ n) — the vertices of thej-th edge. It is guaranteed that you are given correct undirected tree.

The lastmlines contains the description of the queries. Each description starts with the integert

k(1 ≤ tk ≤ 2) — the type of thek-th query. For the queries of the first type then follows two integersvk, ck(1 ≤ vk ≤ n, 1 ≤ ck ≤ 60) — the number of the vertex whose subtree will be recoloured with the colourck. For the queries of the second type then follows integervk(1 ≤ vk ≤ n) — the number of the vertex for which subtree you should find the number of different colours.

Output

For each query of the second type print the integera— the number of different colours in the subtree of the vertex given in the query.

Each of the numbers should be printed on a separate line in order of query appearing in the input.

Examples input
7 10
1 1 1 1 1 1 1
1 2
1 3
1 4
3 5
3 6
3 7
1 3 2
2 1
1 4 3
2 1
1 2 5
2 1
1 6 4
2 1
2 2
2 3
output
2
3
4
5
1
2
input
23 30
1 2 2 6 5 3 2 1 1 1 2 4 5 3 4 4 3 3 3 3 3 4 6
1 2
1 3
1 4
2 5
2 6
3 7
3 8
4 9
4 10
4 11
6 12
6 13
7 14
7 15
7 16
8 17
8 18
10 19
10 20
10 21
11 22
11 23
2 1
2 5
2 6
2 7
2 8
2 9
2 10
2 11
2 4
1 12 1
1 13 1
1 14 1
1 15 1
1 16 1
1 17 1
1 18 1
1 19 1
1 20 1
1 21 1
1 22 1
1 23 1
2 1
2 5
2 6
2 7
2 8
2 9
2 10
2 11
2 4
output
6
1
3
3
2
1
2
3
5
5
1
2
2
1
1
1
2
3
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}
template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}
const int N=4e5+10,M=0,Z=1e9+7,ms63=0x3f3f3f3f;
int n,m,x,y;
int col[N];
int first[N], id; int w[N << 1], nxt[N << 1]; bool vis[N];
int in[N], out[N]; int p[N]; int tim;
LL b[64];
LL C;
struct A
{
	int l,r;
	LL flag;
	LL c;
}a[1<<20];
void ins(int x,int y)
{
	++id;
	w[id]=y;
	nxt[id]=first[x];
	first[x]=id;
}
void dfs(int x)
{
	vis[x]=1;
	in[x]=++tim;
	p[tim]=col[x];
	for(int z=first[x];z;z=nxt[z])
	{
		int y=w[z];
		if(vis[y])continue;
		dfs(y);
	}
	out[x]=tim;
}
void pushdown(int o)
{
	if(a[o].flag)
	{
		a[ls].flag=a[rs].flag=a[o].flag;
		a[ls].c |= a[o].flag;
		a[rs].c |= a[o].flag;
		a[o].flag=0;
	}
}
void pushup(int o)
{
	a[o].c=a[ls].c|a[rs].c;
}
void build(int o,int l,int r)
{
	a[o].l = l;
	a[o].r = r;
	a[o].flag = 0;
	if(l==r)
	{
		a[o].c|=b[ p[l] ];
		return;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(o);
	return;
}
void change(int o,int l,int r,LL v)
{
	if(a[o].l==l&&a[o].r==r)
	{
		a[o].flag = a[o].c = v;
		return;
	}
	pushdown(o);
	int mid=(a[o].l+a[o].r)>>1;
	if(r<=mid)change(ls,l,r,v);
	else if(l>mid)change(rs,l,r,v);
	else
	{
		change(ls,l,mid,v);
		change(rs,mid+1,r,v);
	}
	pushup(o);
}
void update(int o,int l,int r)
{
	if(a[o].flag)
	{
		C |= a[o].flag;
		return;
	}
	if(a[o].l==l&&a[o].r==r)
	{
		C |= a[o].c;
		return;
	}
	int mid=(a[o].l+a[o].r)>>1;
	if(r<=mid)update(ls,l,r);
	else if(l>mid)update(rs,l,r);
	else
	{
		update(ls,l,mid);
		update(rs,mid+1,r);
	}
	pushup(o);
}
int main()
{
	for (int i = 0; i <= 60; ++i)b[i] = 1ll << i;
	while(~scanf("%d%d",&n,&m))
	{
		memset(first,0,n+2<<2);id=1;
		for(int i=1;i<=n;++i)scanf("%d",&col[i]);
		for(int i=1;i<n;++i)
		{
			scanf("%d%d",&x,&y);
			ins(x,y);
			ins(y,x);
		}
		MS(vis,0);
		tim=0;
		dfs(1);
		build(1,1,n);
		for(int i=1;i<=m;++i)
		{
			int o;
			int p,v;
			scanf("%d",&o);
			if(o==1)
			{
				scanf("%d%d",&p,&v);
				change(1,in[p],out[p],b[v]);
			}
			else
			{
				scanf("%d",&p);
				C = 0;
				update(1,in[p],out[p]);
				printf("%d\n", __builtin_popcountll(C));
			}
		}
	}
	return 0;
}
/*
【題意】
給你一棵樹,有n(4e5)個節點,每個節點有一個顏色,顏色範圍在[1,60]
我們有兩種操作。
操作1:把節點p的子樹都改為顏色v
操作2:查詢以p為根的子樹有多少種不同的顏色。

【型別】
線段樹
dfs序

【分析】
我們先得到in和out的dfs序,
然後建線段樹,每個節點開60個bool陣列,表示顏色數
(或者用LL來表示)

然後對於修改操作,使用flag打標記
對於查詢操作,做全域性或運算,然後用__builtin_popcountll()求1的個數即可

【時間複雜度&&優化】
O(mlogn)

*/


相關推薦

Educational Codeforces Round 6E線段 dfsNew Year Tree 顏色修改顏色

E. New Year Tree time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard ou

Educational Codeforces Round 35 A Nearest Minimums

oca ati n) ret 代碼 ini for txt names 【鏈接】 我是鏈接,點我呀:) 【題意】 在這裏輸入題意 【題解】 找出最小的數字的位置。 最近的肯定是相鄰的某對。 【代碼】 #include <bits/stdc++.h&

Educational Codeforces Round 36 C Permute Digits

是的 fine pos .com 如果 ifdef using ons tor 【鏈接】 我是鏈接,點我呀:) 【題意】 在這裏輸入題意 【題解】 //從大到小枚舉第i(1..len1)位 //剩余的數字從小到大排序。 //看看組成的數字是不是小於等於b /

Educational Codeforces Round 36 D Almost Acyclic Graph

pac cati href cor com def eve pan test 【鏈接】 我是鏈接,點我呀:) 【題意】 在這裏輸入題意 【題解】 找到任意一個環。 然後枚舉刪掉其中的某一條邊即可。 (因為肯定要刪掉這個環的,那麽方法自然就是刪掉其中的某一條邊

Educational Codeforces Round 37 EConnected Components?

com 很快 之間 include mar while 它的 所有 conn 【鏈接】 我是鏈接,點我呀:) 【題意】 在這裏輸入題意 【題解】 bfs. 用一個鏈表來記錄哪些點已經確定在某一個聯通快裏了。 一開始每個點都能用。 然後從第一個點開始進行bfs

Educational Codeforces Round 37 A Water The Garden

define 記錄 const log body ace test ret href 【鏈接】 我是鏈接,點我呀:) 【題意】 在這裏輸入題意 【題解】 記錄下水龍頭在哪些位置。 然後每秒鐘把index-i和index+i改變狀態一下就好(置1 【代碼】

Educational Codeforces Round 54---A.........未完成

sin hid str != lag stream char names i++ A---Minimizing the String 1 #include<iostream> 2 #include<cstdio> 3 #include&

Educational Codeforces Round 53 (Rated for Div. 2)-C. Vasya and Robot二分

Educational Codeforces Round 53 (Rated for Div. 2) C. Vasya and Robot 題意 在 二

Educational Codeforces Round 55 (Rated for Div. 2) B. Vova and Trophies暴力+細節題

B. Vova and Trophies 題意 給你一個只有G,S兩種字元的字串,可以交換一次兩個位置的字元,問最終最長的連續的G可以有多少個 2

Educational Codeforces Round 55 (Rated for Div. 2) E. Increasing Frequency滾動陣列優化暴力

E. Increasing Frequency 題意 給你一個數列,你可以選擇在[l,r]區間同時加或者減一個值, 在一次操作後,這個序列最多有多少個值等於c 做法 首先我們要想明白的是,a[l]一定是等於a[r]的 如果a[l]!=a[r],那麼我們肯定可以縮小這個區間,

Educational Codeforces Round 54 (Rated for Div. 2) E. Vasya and a Tree dfs+狀陣列

HEU 大三蒟蒻一枚 有任何問題或建議都可以加Q聯絡我^_^ QQ : 986195894 CodeForces id : lajiyuan CodeForces id : biubiubiu_ Vjudge id : heu2016201206

Educational Codeforces Round 2C貪心最少修改下得到字典儘可能小回文串

A string is called palindrome if it reads the same from left to right and from right to left. For example "kazak", "oo", "r" and "mikhailrubinchikkihcnib

codevs1228蘋果樹線段+dfs

題目描述 Description 在卡卡的房子外面,有一棵蘋果樹。每年的春天,樹上總會結出很多的蘋果。卡卡非常喜歡吃蘋果,所以他一直都精心的呵護這棵蘋果樹。我們知道樹是有很多分叉點的,蘋果會長在枝條的分叉點上面,且不會有兩個蘋果結在一起。卡卡很想知道一個分叉點

Educational Codeforces Round 52 (Rated for Div. 2) F. Up and Down the Tree(DP)

只有兩種情況,一種是訪問一個子樹,最終能回到當前節點,另一種是訪問一個子樹,最後沒法回到當前節點 f[i]表示離i最近的葉子節點到i的深度 dp[i]表示以i為根,並且回到i,能夠訪問的葉子

Educational Codeforces Round 1D DFS求聯通塊

deb types vid cells nta pty http ons mile http://blog.csdn.net/snowy_smile/article/details/49924965 D. Igor In the Museum