记录编号 267394 评测结果 AAAAAAAAAA
题目名称 [HNSDFZ]ZY的钻石树 最终得分 100
用户昵称 GravatarLink 是否通过 通过
代码语言 C++ 运行时间 4.946 s
提交时间 2016-06-11 08:40:31 内存使用 25.20 MiB
显示代码纯文本
/*
题目:
1.修改一个节点的颜色值
2.查询一颗子树中有多少种不同的颜色的值
*/
#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
#pragma warning(disable:4996)
#define NMAX 320000
struct BLOCK {
	int l;
	int r;
};
vector<int> m[NMAX];
vector<int> son[NMAX];
bool v[NMAX];
int pos[NMAX];
int top[NMAX];
int siz[NMAX];
int dep[NMAX];
int p[NMAX];
int endpos[NMAX];
int ccc[NMAX];
int num = 0;
//
int color[NMAX];
int barr[NMAX];
BLOCK block[1200];
int cnt = 0;
int be[NMAX];
int last[NMAX];
int help[1000101];
int sqrtn;
//
int n, q;
bool cmp(const int &a, const int &b) {
	if (last[a] < last[b]) return true;
	else return false;
}
inline int read(){
	int x = 0;
	int f = 1;
	char ch = getchar();
	while (ch<'0' || ch>'9')
	{
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9')
	{
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	return x*f;
}
void dfs(int x) {
	siz[x] = 1;
	v[x] = true;
	int size = m[x].size();
	for (int i = 0; i <= size - 1; i++) {
		int to = m[x][i];
		if (!v[to]) {
			p[to] = x;
			dep[to] = dep[x] + 1;
			son[x].push_back(to);
			dfs(to);
			siz[x] += siz[to];
		}
	}
}
void divide(int x, int topx) {
	num++;
	pos[x] = num;
	top[x] = topx;
	int MaxSon = 0;
	int id = 0;
	int size = son[x].size();
	if (!size) {
		endpos[x] = pos[x];
		return;
	}
	for (int i = 0; i <= size - 1; i++) {
		if (MaxSon < siz[son[x][i]]) {
			MaxSon = siz[son[x][i]];
			id = i;
		}
	}
	divide(son[x][id], topx);
	for (int i = 0; i <= size - 1; i++) {
		if (i != id) {
			divide(son[x][i], son[x][i]);
		}
	}
	endpos[x] = num;
}
void rebulid(int x) {
	for (int i = block[x].l; i <= block[x].r; i++) {
		barr[i] = i;
	}
	sort(barr + block[x].l, barr + block[x].r + 1, cmp);
}
void change(int x, int val) {
	vector<int> blo;
	if (color[x] == val) return;
	int p = help[color[x]];
	int ord = 0;
	if (p == x) {
		help[color[x]] = last[x];
	}
	while (true) {
		if (p == x) {
			last[ord] = last[p];
			blo.push_back(ord);
			last[p] = 0;
			break;
		}
		ord = p;
		p = last[p];
	}
	last[0] = 0;
	ord = 0;
	color[x] = val;
	p = help[color[x]];
	if (p < x) {
		help[color[x]] = x;
	}
	while (true) {
		if (p < x) {
			last[x] = p;
			last[ord] = x;
			blo.push_back(ord);
			break;
		}
		ord = p;
		p = last[p];
	}
	last[0] = 0;
	rebulid(be[x]);
	int size = blo.size();
	for (int i = 0; i <= size - 1; i++)
		rebulid(be[blo[i]]);
}
int  query(int l, int r) {
	int ans = 0;
	if (l > r) swap(l, r);
	if (be[l] == be[r]) {
		for (int i = l; i <= r; i++) {
			if (last[i] < l) ans++;
		}
	}
	else {
		for (int i = l; i <= block[be[l]].r; i++) {
			if (last[i] < l) ans++;
		}
		for (int i = block[be[r]].l; i <= r; i++) {
			if (last[i] < l) ans++;
		}
		for (int i = be[l] + 1; i <= be[r] - 1; i++) {
			for (int j = block[i].l; j <= block[i].r; j++)
				if (last[barr[j]] < l) ans++;
				else break;
		}
	}
	return ans;
}
void GetBlock() {
	sqrtn = (int)sqrt(n);
	if (n%sqrtn) cnt = (n / sqrtn) + 1;
	else cnt = n / sqrtn;
	for (int i = 1; i <= cnt; i++) {
		block[i].l = block[i - 1].r + 1;
		block[i].r = block[i].l + sqrtn - 1;
	}
	block[cnt].r = n;
	for (int i = 1; i <= cnt; i++) {
		for (int j = block[i].l; j <= block[i].r; j++)
			be[j] = i;
	}
	for (int i = 1; i <= n; i++) {
		last[i] = help[color[i]];
		help[color[i]] = i;
	}
	for (int i = 1; i <= cnt; i++) {
		rebulid(i);
	}
}
void Init() {
	n = read();
	for (int i = 1; i <= n; i++) {
		ccc[i] = read();
	}
	for (int i = 1; i <= n - 1; i++) {
		int u = read();
		int v = read();
		m[u].push_back(v);
		m[v].push_back(u);
	}
	q = read();
	dfs(1);
	divide(1, 1);
	for (int i = 1; i <= n; i++) {
		color[pos[i]] = ccc[i];
	}
	GetBlock();
	
}
int main() {

	freopen("zytree.in", "r", stdin);
	freopen("zytree.out", "w", stdout);
	Init();
	for (int i = 1; i <= q; i++) {
		int k = read();
		if (k) {
			int x = read();
			printf("%d\n", query(pos[x], endpos[x]));
		}else {
			int x = read();
			int c = read();
			change(pos[x], c);
		}
	}
	
}