记录编号 |
365523 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[HZOI 2015] 树黑白 |
最终得分 |
100 |
用户昵称 |
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;
}