记录编号 223824 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2012]tree(伍一鸣) 最终得分 100
用户昵称 Gravatar/k 是否通过 通过
代码语言 C++ 运行时间 9.179 s
提交时间 2016-02-13 17:35:16 内存使用 3.85 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#define mod 51061
#define ll unsigned int
using namespace std;
int n,l;
/*struct u
{
	int b;
	int x;
}c[200000];h[100010],*/
int f[100010];
unsigned int bjia[100010],bcheng[100010],w[100010],z[100010];
bool /*bv[100010],*/b[100010];
int Z[100010],Y[100010],st[100010];
int s[100010];
inline bool grt(int a)
{
	return (f[a]==0||(Z[f[a]]!=a&&Y[f[a]]!=a));
}
inline void gy(int x)
{
	int y=f[x];
	int z=f[y];
	if(Z[z]==y)
	    Z[z]=x;
	else
	    if(Y[z]==y)
	        Y[z]=x;
	 f[x]=z;
	 f[Y[x]]=y;
	 Z[y]=Y[x];
	 f[y]=x;
	 Y[x]=y;
}
inline void gz(int x)
{
	int y=f[x];
	int z=f[y];
	if(Z[z]==y)
	    Z[z]=x;
	else
	    if(Y[z]==y)
	        Y[z]=x;
	 f[x]=z;
	 f[Z[x]]=y;
	 Y[y]=Z[x];
	 f[y]=x;
	 Z[x]=y;
}
inline void Updata(int a)
{
	z[0]=w[0]=s[0]=0;
	z[a]=w[a]+z[Z[a]]+z[Y[a]];
	z[a]%=mod;
	s[a]=s[Z[a]]+s[Y[a]]+1;
}
inline void Pcheng(int a)
{
	if(bcheng[a]!=1)
	{
		if(Z[a])
		{
		//	if(bjia[Z[a]]>0)
			//	Pushdown(Z[a]);
			bcheng[Z[a]]*=bcheng[a];
			bcheng[Z[a]]%=mod;
			bjia[Z[a]]*=bcheng[a];
			bjia[Z[a]]%=mod;
			w[Z[a]]*=bcheng[a];
			w[Z[a]]%=mod;
			z[Z[a]]*=bcheng[a];
			z[Z[a]]%=mod;
		}
		if(Y[a])
		{
			//if(bjia[Y[a]])
			//	Pushdown(Y[a]);
			bcheng[Y[a]]*=bcheng[a];
			bcheng[Y[a]]%=mod;
			bjia[Y[a]]*=bcheng[a];
			bjia[Y[a]]%=mod;
			w[Y[a]]*=bcheng[a];
			w[Y[a]]%=mod;
			z[Y[a]]*=bcheng[a];
			z[Y[a]]%=mod;
		}
		bcheng[a]=1;
	}
}
inline void Pushdown(int a)
{
	if(a==0)
	    return;
	if(b[a])
	{
		b[a]=0;
		b[Z[a]]^=1;
		b[Y[a]]^=1;
		swap(Z[a],Y[a]);
	}
	Pcheng(a);
	if(bjia[a])
	{
		if(Z[a])
		{
			//if(bcheng[Z[a]]>1)
			//	Pushdown(Z[a]);
			bjia[Z[a]]+=bjia[a];
			bjia[Z[a]]%=mod;
			w[Z[a]]+=bjia[a];
			w[Z[a]]%=mod;
			z[Z[a]]+=bjia[a]*s[Z[a]];
			z[Z[a]]%=mod;
		}
		if(Y[a])
		{
			//if(bcheng[Y[a]]>1)
			//	Pushdown(Y[a]);
			bjia[Y[a]]+=bjia[a];
			bjia[Y[a]]%=mod;
			w[Y[a]]+=bjia[a];
			w[Y[a]]%=mod;
			z[Y[a]]+=bjia[a]*s[Y[a]];
			z[Y[a]]%=mod;
		}
		bjia[a]=0;
	}
	Updata(a);
}/*
inline void gj(int a,int b)
{
	c[++l].b=b;
	c[l].x=h[a];
	h[a]=l;
}*/
inline void Splay(int x)
{
	int y=x,t=1;
	st[t]=y;
	while(!grt(y))
	{
		y=f[y];
		st[++t]=y;
	}
	for(int i=t;i>=1;i--)
	    Pushdown(st[i]);
	for(int i=1;i<=t;i++)
	    Updata(st[i]);
	while(!grt(x))
	{
		y=f[x];
		if(Y[y]==x)
		    gz(x);
		else
		    gy(x);
		Updata(y);
		Updata(x);
	}
}
inline void Access(int x)
{
	int t=0;
	while(x)
	{
	//if(x==3)
	 //   printf("T%d %d\n",Z[1],grt(3));
		Splay(x);
		Y[x]=t;
		Updata(x);
		t=x;
		x=f[x];
	}
}
inline void Mroot(int x)
{
	Access(x);
	Splay(x);
	b[x]^=1;
}
inline void Link(int father,int son)
{
	Mroot(son);
	f[son]=father;
	Updata(son);
	Updata(father);
}/*
inline void gdfs(int a)
{
	bv[a]=1;
	for(int i=h[a];i;i=c[i].x)
	{
		int u=c[i].b;
		if(bv[u])
		    continue;
		Link(a,u);
		gdfs(u);
	}
}*/
inline void gjia()
{
	ll aa,bb,cc;
	scanf("%d%d%d",&aa,&bb,&cc);
	cc%=mod;
	Mroot(aa);
	Access(bb);
	Splay(aa);
	//if(bcheng[Y[aa]]>1)
	//	Pushdown(Y[aa]);
	Pcheng(aa);
	w[aa]+=cc;
	w[aa]%=mod;
	z[aa]+=cc*s[aa];
	z[aa]%=mod;
	bjia[aa]+=cc;
	bjia[aa]%=mod;
	Updata(aa);
}
inline void gcheng()
{
	ll aa,bb,cc;
	scanf("%d%d%d",&aa,&bb,&cc);
	cc%=mod;
	Mroot(aa);
	Access(bb);
	Splay(aa);
	//if(bjia[Y[aa]]!=0)
	//	Pushdown(Y[aa]);
	w[aa]*=cc;
	w[aa]%=mod;
	z[aa]*=cc;
	z[aa]%=mod;
	bcheng[aa]*=cc;
	bcheng[aa]%=mod;
	//printf("?%d ",cc);
	//for(int i=1;i<=n;i++)
	//    printf("N %d %d %d\n",i,Z[i],Y[i]);
	//printf("?%d\n",bcheng[2]);
	Updata(aa);
}
inline void gw()
{
	int aa,bb;
	scanf("%d%d",&aa,&bb);
	Mroot(aa);
	Access(bb);
	Splay(aa);
	printf("%d\n",z[aa]%mod);
}
inline void Cut(int father,int son)
{
	Mroot(son);
	Access(father);
	Splay(father);
	f[son]=0;
	Z[father]=0;
	Updata(son);
	Updata(father);
}
int main()
{
    freopen("nt2012_wym_tree.in","r",stdin);
	freopen("nt2012_wym_tree.out","w",stdout);
	int Q;
	scanf("%d",&n);
	scanf("%d",&Q);
	for(int i=0;i<=n;i++)
	    s[i]=bcheng[i]=z[i]=w[i]=1;
	for(int i=1;i<n;i++)
	{
		ll aa,bb;
		scanf("%d%d",&aa,&bb);
		Link(aa,bb);
	/*	bcheng[i]=1;
		z[i]=w[i]=1;*/
	}
	/*bcheng[0]=1;
	bcheng[n]=1;
	z[n]=w[n]=1;*/
	//printf("R%d %d\n",grt(3),Y[2]);
	while(Q--)
	{
		char ss[3];
		scanf("%s",ss);
		if(ss[0]=='R')
		    break;
		if(ss[0]=='+')
		{
			gjia();
		}
		else if(ss[0]=='-')
		{
			ll aa,bb,cc,dd;
			scanf("%d%d%d%d",&aa,&bb,&cc,&dd);
			Cut(aa,bb);
			Link(cc,dd);
		}
		else if(ss[0]=='*')
		{
			gcheng();
		}
		else
		{
			gw();
		}
	}
	//while(1);
}