记录编号 365523 评测结果 AAAAAAAAAA
题目名称 [HZOI 2015] 树黑白 最终得分 100
用户昵称 Gravatar‎MistyEye 是否通过 通过
代码语言 C++ 运行时间 0.687 s
提交时间 2017-01-20 19:25:27 内存使用 72.03 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cctype>
using namespace std;
int read() {
	int x=0; char ch;
	while(ch=getchar(), !isdigit(ch));
	x = ch-'0';
	while(ch=getchar(), isdigit(ch)) x = x*10+ch-'0';
	return x;
}
const int maxn = 200005, maxd = 20;
struct Edge {
	int next, to, dis;
	Edge(int a=0, int b=0, int c=0) :
		next(a), to(b), dis(c) {}
} e[maxn<<1];
int head[maxn], tot;
void Add(int u, int v, int w) {
	e[++tot] = Edge(head[u], v, w); head[u] = tot;
}
int N, Q, F, Size, root, size[maxn], vis[maxn];
int fa[maxn], res[maxn];
int dis[maxn][maxd], sub[maxn][maxd];
int sum[maxn], num[maxn], black[maxn];
int sums[maxn][maxd], nums[maxn][maxd];

void invert(int x) {
	black[x] ^= 1;
	int mk = black[x] ? 1 : -1;
	num[x] += mk;
	for(int y=fa[x], r=res[x]-1; y; y=fa[y], --r) {
		num[y] += mk;
		sum[y] += mk*dis[x][r];
		nums[sub[x][r]][r] += mk;
		sums[sub[x][r]][r] += mk*dis[x][r];
	}
}
int query(int x) {
	int ans = sum[x]; //warn
	for(int y=fa[x], r=res[x]-1; y; y=fa[y], --r) {
		ans += sum[y]-sums[sub[x][r]][r];
		ans += dis[x][r]*(num[y]-nums[sub[x][r]][r]);
	}
	return ans;
}
void getdep(int x, int fa, int Sub, int Res) {
	sub[x][Res] = Sub;
	for(int i=head[x]; i; i=e[i].next) {
		int to = e[i].to;
		if(vis[to] || to==fa) continue;
		dis[to][Res] = dis[x][Res]+e[i].dis;
		getdep(to, x, Sub, Res);
	}
}
void build(int x) {
	for(int i=head[x]; i; i=e[i].next) {
		int to = e[i].to;
		if(vis[to]) continue;
		dis[to][res[x]] = e[i].dis;
		getdep(to, x, to, res[x]);
	}
}
int getroot(int x, int fa) {
	int f = 0; size[x] = 1;
	for(int i=head[x]; i; i=e[i].next) {
		int to = e[i].to;
		if(vis[to] || to==fa) continue;
		size[x] += getroot(to, x);
		f = max(f, size[to]);
	}
	f = max(f, Size-size[x]);
	if(f<=F) F = f, root = x;
	return size[x];
}
void Build(int x) {
	vis[x] = 1; build(x);
	for(int i=head[x]; i; i=e[i].next) {
		int to = e[i].to;
		if(vis[to]) continue;
		F = Size = size[to]; getroot(to, -1);
		fa[root] = x;
		res[root] = res[x]+1;
		Build(root); 
	}
}
int main() {
	freopen("A_Tree.in","r",stdin);
	freopen("A_Tree.out","w",stdout);
	N = read(), Q = read();
	for(int i=1,a,b,c; i<N; ++i) {
		a = read(), b = read(), c = read();
		Add(a, b, c); Add(b, a, c);
	}
	F = Size = N; getroot(1, -1);
	res[root] = 1, Build(root);
	char ch[2]; int v;
	while(Q--) {
		scanf("%s", ch); v = read();
		if(ch[0]=='Q') printf("%d\n", query(v));
		else invert(v);
	}
	getchar(), getchar();
	return 0;
}