记录编号 481365 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2012]tree(伍一鸣) 最终得分 100
用户昵称 GravatarHallmeow 是否通过 通过
代码语言 C++ 运行时间 3.569 s
提交时间 2018-01-02 15:58:58 内存使用 7.21 MiB
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
using namespace std;
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define pos2(i,a,b) for(int i=(a);i>=(b);i--)
#define lc(x) (ch[x][0])
#define rc(x) (ch[x][1])
#define N 201000
#define int unsigned int
const int p=51061;
char xB[(1<<15)+10],*xS=xB,*xT=xB;
#define gtc (xS==xT&&(xT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xT)?0:*xS++)
inline void read(int &xx){
    register char ch1=gtc;
    for(xx=0;ch1<'0'||ch1>'9';ch1=gtc);
    for(;ch1>='0'&&ch1<='9';xx=(xx<<1)+(xx<<3)+ch1-'0',ch1=gtc);
}
int fa[N],ch[N][2],size[N],reverse[N];
int add[N],sum[N],mul[N],v[N];
int get(int x){return rc(fa[x])==x;}
inline void update(int x){
	if(x){
		size[x]=size[lc(x)]+size[rc(x)]+1;
		sum[x]=(v[x]+sum[lc(x)]+sum[rc(x)])%p;
	}
}
inline void mark(int x,int y,int z){
	v[x]=(v[x]*z+y)%p;
	sum[x]=(sum[x]*z+size[x]*y)%p;
	add[x]=(add[x]*z+y)%p;
	mul[x]=(mul[x]*z)%p;
}
inline void pushdown(int x){
	if(x){
		if(reverse[x]){
			swap(lc(x),rc(x));
			if(lc(x)) reverse[lc(x)]^=1;
			if(rc(x)) reverse[rc(x)]^=1;
			reverse[x]=0;
		}
		if(add[x]!=0||mul[x]!=1){
			if(lc(x)) mark(lc(x),add[x],mul[x]);
			if(rc(x)) mark(rc(x),add[x],mul[x]);
			add[x]=0;mul[x]=1;
		}	
	}
}
inline int isroot(int x){return lc(fa[x])!=x&&rc(fa[x])!=x;}
inline void rotate(int x){
	int old=fa[x],oldf=fa[old],d=get(x);
	if(!isroot(old)) ch[oldf][rc(oldf)==old]=x;
	fa[x]=oldf;
	ch[old][d]=ch[x][d^1];
	fa[ch[old][d]]=old;
	ch[x][d^1]=old;fa[old]=x;
	update(old);update(x);
}
int stack[N],hea;
inline void splay(int x){
	hea=0;stack[++hea]=x;
	for(int i=x;!isroot(i);i=fa[i]) stack[++hea]=fa[i];
	pos2(i,hea,1) pushdown(stack[i]);
	for(int f;!isroot(x);rotate(x)){
		if(!isroot(f=fa[x])) rotate((get(x)==get(f))?f:x);
	}
}
inline void access(int x){for(int t=0;x;t=x,x=fa[x]){splay(x);rc(x)=t;update(x);}}
inline void makeroot(int x){access(x);splay(x);reverse[x]^=1;}
inline void link(int x,int y){makeroot(x);fa[x]=y;}
inline void cut(int x,int y){makeroot(x);access(y);splay(y);lc(y)=fa[x]=0;}
inline void Add(int x,int y,int z){makeroot(x);access(y);splay(y);mark(y,z,1);}
inline void Mul(int x,int y,int z){makeroot(x);access(y);splay(y);mark(y,0,z);}
inline int query(int x,int y){makeroot(x);access(y);splay(y);return sum[y];}
int n,q;
signed main(){
	freopen("nt2012_wym_tree.in","r",stdin);
	freopen("nt2012_wym_tree.out","w",stdout);
	read(n);read(q);
	pos(i,1,n) v[i]=mul[i]=1;
	pos(i,1,n-1){
		int x,y;read(x);read(y);
		link(x,y);
	}
	pos(i,1,q){
		char opt=gtc;
        while (opt!='+'&&opt!='-'&&opt!='*'&&opt!='/') opt=gtc;
		int x,y,z,w;read(x);read(y);
		if(opt=='+'){
			read(z);Add(x,y,z);continue;
		}
		if(opt=='-'){
			read(z);read(w);cut(x,y);link(z,w);continue;
		}
		if(opt=='*'){
			read(z);Mul(x,y,z);continue;
		}
		if(opt=='/'){
			printf("%d\n",query(x,y)%p);
		}
	}
	return 0;
}