记录编号 248006 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2012]tree(伍一鸣) 最终得分 100
用户昵称 Gravatarmikumikumi 是否通过 通过
代码语言 C++ 运行时间 14.977 s
提交时间 2016-04-09 21:50:24 内存使用 3.56 MiB
显示代码纯文本
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
const int SIZEN=100010,MOD=51061;
typedef long long LL;
int N,M;
class miku
{
public:
	int son[2],fa;
	unsigned int sum,val,add,mul,siz;
	bool rev;
	miku()
	{
		fa=son[0]=son[1]=0;
		val=sum=mul=siz=1;add=0;
	}
	#define sum(x) tr[x].sum
	#define val(x) tr[x].val
	#define mul(x) tr[x].mul
	#define siz(x) tr[x].siz
	#define rev(x) tr[x].rev
	#define add(x) tr[x].add
	#define fa(x) tr[x].fa
	#define ls(x) tr[x].son[0]
	#define rs(x) tr[x].son[1]
}tr[SIZEN];
void update(int x)
{
	if(!x) return;
	sum(x)=(sum(ls(x))+sum(rs(x))+val(x))%MOD;
	siz(x)=siz(ls(x))+siz(rs(x))+1;
}
void Node_mul(int x,int t)
{
	if(!x) return;
	sum(x)=(sum(x)*t)%MOD;
	add(x)=(add(x)*t)%MOD;
	val(x)=(val(x)*t)%MOD;
	mul(x)=(mul(x)*t)%MOD;
}
void Node_add(int x,int t)
{
	if(!x) return;
	sum(x)=(sum(x)+t*siz(x))%MOD;
	val(x)=(val(x)+t)%MOD;
	add(x)=(add(x)+t)%MOD;
}
void pushdown(int x)
{
	if(mul(x)!=1)
	{
		Node_mul(ls(x),mul(x));
		Node_mul(rs(x),mul(x));
		mul(x)=1;
	}
	if(add(x)!=0)
	{
		Node_add(ls(x),add(x));
		Node_add(rs(x),add(x));
		add(x)=0;
	}
	if(rev(x))
	{
		rev(x)^=1;
		swap(ls(x),rs(x));
		if(ls(x)) rev(ls(x))^=1;
		if(rs(x)) rev(rs(x))^=1;
	}
}
bool isroot(int x)
{
	if(fa(x)==0) return 1;
	if(ls(fa(x))==x||rs(fa(x))==x) return 0;
	return 1;
}
void rotate(int x)
{
	int y=tr[x].fa,z=tr[y].fa,l,r;
	if(tr[y].son[0]==x) l=0;
	else l=1;
	r=l^1;
	if(!isroot(y))
	{
		if(tr[z].son[0]==y) tr[z].son[0]=x;
		else tr[z].son[1]=x;
	}
	tr[tr[x].son[r]].fa=y;tr[x].fa=z;tr[y].fa=x;
	tr[y].son[l]=tr[x].son[r];tr[x].son[r]=y;
	update(y);update(x);
}
void splay(int x)
{
	pushdown(x);
	while(!isroot(x))
	{
		int y=fa(x),z=fa(y);
		pushdown(z);pushdown(y);pushdown(x);
		if(!isroot(y))
		{
			if((tr[y].son[0]==x)^(tr[z].son[0]==y)) rotate(x);
			else rotate(y);
		}
		rotate(x);
	}
}
void access(int x)
{
	int v=0;
	while(x)
	{
		splay(x);
		tr[x].son[1]=v;
		update(x);
		v=x;
		x=tr[x].fa;
	}
}
void make_root(int x)
{
	access(x);
	splay(x);
	tr[x].rev^=1;
}
void link(int u,int v)
{
	make_root(v);
	//splay(v);
	fa(v)=u;
}
void read()
{
	scanf("%d%d",&N,&M);
	int fr,to;
	for(int i=1;i<N;i++)
	{
		scanf("%d%d",&fr,&to);
		link(fr,to);
	}
}
void Path_mul(int x,int y,int t)
{
	make_root(x);
	access(y);
	splay(y);
	Node_mul(y,t);
}
void Path_add(int x,int y,int t)
{
	make_root(x);
	access(y);
	splay(y);
	Node_add(y,t);
}
void cut(int x,int y)
{
	make_root(x);
	access(y);
	splay(x);
	rs(x)=0;fa(y)=0;
	update(x);
}
int query(int x,int y)
{
	make_root(x);
	access(y);
	splay(y);
	return sum(y);
}
void work()
{
	char c;
	int fr,to,w;
	int u,v;
	for(int i=1;i<=M;i++)
	{
		while(true)
		{
			c=getchar();
			if(c!='\n'&&c!='\r') break;
		}
		//cout<<c<<endl;
		if(c=='*') 
		{
			scanf("%d%d%d",&fr,&to,&w);
			Path_mul(fr,to,w);
		}
		if(c=='/')
		{
			scanf("%d%d",&fr,&to);
			int ans=query(fr,to);
			printf("%d\n",ans);
		}
		if(c=='+')
		{
			scanf("%d%d%d",&fr,&to,&w);
			Path_add(fr,to,w);
		}
		if(c=='-')
		{
			scanf("%d%d%d%d",&fr,&to,&u,&v);
			cut(fr,to);
			link(u,v);
		}
	}
}
int main()
{
	freopen("nt2012_wym_tree.in","r",stdin);
	freopen("nt2012_wym_tree.out","w",stdout);
	tr[0].val=tr[0].sum=tr[0].add=tr[0].siz=0;
	read();
	work();
	return 0;
}