记录编号 383282 评测结果 AAAAAAAAAA
题目名称 [HZOI 2015] 树黑白 最终得分 100
用户昵称 GravatarL_in 是否通过 通过
代码语言 C++ 运行时间 0.941 s
提交时间 2017-03-15 17:07:57 内存使用 71.66 MiB
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 200010
using namespace std;
typedef long long ll;
int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')x=10*x+ch-'0',ch=getchar();
	return x*f;
}
int n,m;
struct Edge{
	int to,next,w;
}e[maxn<<1];
int head[maxn],tot;
void add(int from,int to,int w){
	e[++tot].w=w;
	e[tot].to=to;
	e[tot].next=head[from];
	head[from]=tot;
}
bool b[maxn],vis[maxn];
int rt,cnt,size[maxn],son[maxn];
int dis[20][maxn],sub[20][maxn];//第Deep层x到其rt的dis | 并不知道为什么不是到rt 
int sums[20][maxn],nums[20][maxn];
int fa[maxn],deep[maxn],sum[maxn],num[maxn];//子树中的dis
void g(int x,int fa){
	size[x]=1;son[x]=0;
	for(int i=head[x];i;i=e[i].next){
		int to=e[i].to;
		if(to==fa||vis[to])continue;
		g(to,x);size[x]+=size[to];
		son[x]=max(son[x],size[to]);
	}
	son[x]=max(son[x],cnt-size[x]);
	if(!rt||son[x]<son[rt])rt=x;
}
void reverse(int x){
	b[x]=!b[x];
	int mk=b[x]?1:-1;
	for(int y=x,r=deep[x];y;y=fa[y],r--){
		num[y]+=mk;sum[y]+=mk*dis[r][x];//以i为根的子树黑点个数 | sigma dis
		nums[r][sub[r][x]]+=mk;//r层,rt的某个son的黑点个数
		sums[r][sub[r][x]]+=mk*dis[r][x];//同上
	}
}
int query(int x){
	int ans=sum[x];
	for(int y=fa[x],r=deep[x]-1;y;y=fa[y],r--){
		ans+=sum[y]-sums[r][sub[r][x]];
		ans+=dis[r][x]*(num[y]-nums[r][sub[r][x]]);
	}return ans;
}
void get_deep(int x,int fa,int Sub,int Deep){
	sub[Deep][x]=Sub;//看起来是deep层,x belong rt的哪个son
	for(int i=head[x];i;i=e[i].next){
		int to=e[i].to;
		if(vis[to]||to==fa)continue;
		dis[Deep][to]=dis[Deep][x]+e[i].w;
		get_deep(to,x,Sub,Deep);
	}
}
void build(int x,int Deep){
	for(int i=head[x];i;i=e[i].next){
		int to=e[i].to;
		if(vis[to])continue;
		dis[Deep][to]=e[i].w;//Deep层,to到其rt的dis
		get_deep(to,x,to,Deep);
	}
}
void Build(int x){
	vis[x]=true;
	build(x,deep[x]);//deep[x]层以x为rt
	for(int i=head[x];i;i=e[i].next){
		int to=e[i].to;
		if(vis[to])continue;
		cnt=size[to];rt=0;g(to,x);
		fa[rt]=x;//fa:上一层的rt
		deep[rt]=deep[x]+1;
		Build(rt);
	}
}
int main(){
	freopen("A_Tree.in","r",stdin);
	freopen("A_Tree.out","w",stdout);
	n=read();m=read();
	int u,v,w;
	for(int i=1;i<n;i++){
		u=read();v=read();w=read();
		add(u,v,w);add(v,u,w);
	}
	cnt=n;g(1,0);
	deep[rt]=1;Build(rt);
	char op[5];
	for(int i=1;i<=m;i++){
		scanf("%s",op);u=read();
		if(op[0]=='Q')printf("%d\n",query(u));
		else reverse(u);
	}
	fclose(stdin);fclose(stdout);
	return 0;
}