记录编号 558200 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2008]树的统计Count 最终得分 100
用户昵称 Gravatarfsdh 是否通过 通过
代码语言 C++ 运行时间 1.313 s
提交时间 2020-12-13 21:46:43 内存使用 4.39 MiB
显示代码纯文本
#include <cstdio>
#include <algorithm>
#include <cstring>
#define Debug puts ("Debug");
using namespace std;
const int MAXN = 3e4 + 5;
struct Edge {
	int next, to;
}edge[MAXN << 1];
int head[MAXN], cnt = 0;
struct Tree {
	int f, dep, size, son, top, seg;
}tree[MAXN];
struct Segment {
	int sum, maxn;
}t[MAXN << 2];
int n, w[MAXN], m, ansq, ansm;
int rev[MAXN];

template <typename T>
inline void read (T &x) {
	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 << 1) + (x << 3) + (ch - '0'), ch = getchar ();
	x *= t; return ;
}

inline void add (int from, int to) {
	edge[++ cnt].next = head[from]; head[from] = cnt; edge[cnt].to = to;
	edge[++ cnt].next = head[to]; head[to] = cnt; edge[cnt].to = from;
	return ;
}

inline void dfs1 (int u, int fa) {
	tree[u].size = 1, tree[u].f = fa, tree[u].dep = tree[fa].dep + 1;
	for (int q = head[u]; ~q; q = edge[q].next) {
		int v = edge[q].to;
		if (v == fa) continue ;
		dfs1 (v, u);
		tree[u].size += tree[v].size;
		if (tree[v].size > tree[tree[u].son].size) tree[u].son = v;
	} return ; 
}

inline void dfs2 (int u, int fa) {
	if (tree[u].son) {
		tree[tree[u].son].seg = ++tree[0].seg, tree[tree[u].son].top = tree[u].top;
		rev[tree[0].seg] = tree[u].son, dfs2 (tree[u].son, u);
	}
	for (int q = head[u]; ~q; q = edge[q].next) {
		int v = edge[q].to;
		if (v == fa || v == tree[u].son) continue ;
		tree[v].seg = ++tree[0].seg, tree[v].top = v;
		rev[tree[0].seg] = v;
		dfs2 (v, u);
	} return ;
}

inline void pushup (int i) {
	t[i].sum = t[i << 1].sum + t[i << 1 | 1].sum;
	t[i].maxn = max (t[i << 1].maxn, t[i << 1 | 1].maxn); return ;
}

inline void build (int i, int l, int r) {
	if (l == r) { t[i].sum = t[i].maxn = w[rev[l]]; return ; }
	int mid = (l + r) >> 1;
	build (i << 1, l, mid); build (i << 1 | 1, mid + 1, r);
	pushup (i); return ;
}

inline void change (int i, int l, int r, int val, int x) {
	if (l > x || r < x) return ;
	if (l == r && l == x) { t[i].sum = t[i].maxn = val; return ; }
	int mid = (l + r) >> 1;
	if (x <= mid) change (i << 1, l, mid, val, x);
	else change (i << 1 | 1, mid + 1, r, val, x);
	pushup (i); return ;
}

inline void query_s (int i, int l, int r, int L, int R) {
	if (l >= L && r <= R) {
		ansq += t[i].sum; ansm = max (ansm, t[i].maxn);
		return ;
	}
	if (l > R || r < L) return ;
	int s = 0, mid = (l + r) >> 1;
	if (mid >= L) query_s (i << 1, l, mid, L, R);
	if (mid < R) query_s (i << 1 | 1, mid + 1, r, L, R);
	return ;
}

inline void ask (int x, int y) {
	int fx = tree[x].top, fy = tree[y].top;
	while (fx != fy) {
		if (tree[fx].dep < tree[fy].dep) swap (fx, fy), swap (x, y);
		query_s (1, 1, tree[0].seg, tree[fx].seg, tree[x].seg);
		x = tree[fx].f, fx = tree[x].top;
	}
	if (tree[x].dep < tree[y].dep) swap (x, y);
	query_s (1, 1, tree[0].seg, tree[y].seg, tree[x].seg);
	return ;
}

int main () {
	memset (head, -1, sizeof (head));
	freopen ("bzoj_1036.in", "r", stdin);
	freopen ("bzoj_1036.out", "w", stdout);
	scanf ("%d", &n);
	for (int q = 1, a, b; q < n; ++q) {
		scanf ("%d%d", &a, &b);
		add (a, b);
	}
	for (int q = 1; q <= n; ++q) scanf ("%d", &w[q]);
	dfs1 (1, 0); tree[0].seg = tree[1].seg = rev[1] = tree[1].top = 1;
	dfs2 (1, 0); build (1, 1, tree[0].seg);
	scanf ("%d", &m);
	int x, y; char op[11]; 
	while (m--) {
		scanf ("%s", op); scanf ("%d%d", &x, &y);
		if (op[0] == 'C') change (1, 1, tree[0].seg, y, tree[x].seg);
		else {
			ansm = -0x3f3f3f3f, ansq = 0;
			ask (x, y);
			if (op[1] == 'S') {
				printf ("%d\n", ansq);
			}
			else printf ("%d\n", ansm);
		}
	}
	return 0;
}