记录编号 252539 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2012]tree(伍一鸣) 最终得分 100
用户昵称 GravatarFmuckss 是否通过 通过
代码语言 C++ 运行时间 6.497 s
提交时间 2016-04-20 16:34:10 内存使用 3.56 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
using namespace std;
typedef unsigned int UI;
const int maxn = 1e5+10;
const int lcy = 51061;

class link_cut_tree {
private:
	struct node{
		int ls, rs, fa, size;
		bool revc;
		UI mul, add, sum, v;
		node() {
			ls = rs = fa = add = revc = 0;
			size = sum = mul = v = 1;
		}
	}ns[maxn];
	
	inline void make_mul(int tar, int v) {
		if(!tar) return;
		ns[tar].v	= (ns[tar].v * v) 	% lcy;
		ns[tar].sum = (ns[tar].sum * v) % lcy;
		ns[tar].add = (ns[tar].add * v) % lcy;
		
		ns[tar].mul = (ns[tar].mul * v) % lcy;
	}
	
	inline void make_add(int tar, int v) {
		if(!tar) return;
		ns[tar].v	= (ns[tar].v + v) % lcy;
		ns[tar].sum = (ns[tar].sum + ns[tar].size * v) % lcy;
		
		ns[tar].add = (ns[tar].add + v) % lcy;
	}
	
	inline void make_revc(int tar) {
		if(!tar) return;
		swap(ns[tar].ls, ns[tar].rs);
		
		ns[tar].revc ^= 1;
	}
	
	inline void update(int tar) {
		if(!tar) return;
		ns[tar].size = ns[ns[tar].ls].size + ns[ns[tar].rs].size + 1;
		ns[tar].sum  = ns[ns[tar].ls].sum % lcy + ns[ns[tar].rs].sum % lcy  + ns[tar].v;
		ns[tar].sum %= lcy;
	}
	
	inline void push_down(int tar) {
		if(!tar) return;
		if(ns[tar].mul != 1) {
			make_mul(ns[tar].ls, ns[tar].mul);
			make_mul(ns[tar].rs, ns[tar].mul);
			ns[tar].mul = 1;
		}
		if(ns[tar].add) {
			make_add(ns[tar].ls, ns[tar].add);
			make_add(ns[tar].rs, ns[tar].add);
			ns[tar].add = 0; 
		}
		if(ns[tar].revc) {
			make_revc(ns[tar].ls);
			make_revc(ns[tar].rs);
			ns[tar].revc ^= 1;
		}
	}
	
	inline void zig(int &tar) {
		int fa = ns[tar].fa;
		if(ns[ns[fa].fa].ls == fa) ns[ns[fa].fa].ls = tar;
		if(ns[ns[fa].fa].rs == fa) ns[ns[fa].fa].rs = tar;
		ns[tar].fa = ns[fa].fa;
		ns[ns[tar].rs].fa = fa;
		ns[fa].ls = ns[tar].rs;
		ns[tar].rs = fa, ns[fa].fa = tar;
		update(fa);
	} 
	
	inline void zag(int &tar) {
		int fa = ns[tar].fa;
		if(ns[ns[fa].fa].ls == fa) ns[ns[fa].fa].ls = tar;
		if(ns[ns[fa].fa].rs == fa) ns[ns[fa].fa].rs = tar;
		ns[tar].fa = ns[fa].fa;
		ns[ns[tar].ls].fa = fa;
		ns[fa].rs = ns[tar].ls;
		ns[tar].ls = fa, ns[fa].fa = tar;
		update(fa);
	}
	
	inline bool is_root(int &tar) {
		int fa = ns[tar].fa;
		return ns[fa].ls != tar && ns[fa].rs != tar;
	}


	void outer(int now) {
		printf("now = %d ls = %d rs = %d fa = %d v = %d sum = %d\n",
		now, ns[now].ls, ns[now].rs, ns[now].fa, ns[now].v, ns[now].sum);
	}


	void out() {
		printf("\n");
		for(int i = 0; i <= 3; i++) {
			outer(i);
		}
	}


	inline void splay(int now) {
		int fa;
		bool done = false;
		push_down(now);
		while(!is_root(now)) {
			fa = ns[now].fa;
			push_down(ns[fa].fa), push_down(fa), push_down(now);
			if(is_root(fa)) {
				ns[fa].ls == now ? zig(now) : zag(now);
				break;
			}
			else {
				if(ns[ns[fa].fa].ls == fa) ns[fa].ls == now ? zig(fa) : zag(now), zig(now);
				else ns[fa].rs == now ? zag(fa) : zig(now), zag(now);
			}
		}
		update(now);
	}
	


	inline void access(int tar) {
		int la = 0;
		while(tar) {
			splay(tar);
			ns[tar].rs = la;
			update(tar);
			la = tar;
			tar = ns[tar].fa;
		}
	}

	inline void make_root(int tar) {
		access(tar);
		splay(tar);
		make_revc(tar);
	}
	
public:
	link_cut_tree() { ns[0].sum = ns[0].mul = ns[0].v = ns[0].size = 0; }
	
	inline void link(int u, int v) {
		make_root(v);
		ns[v].fa = u;
	}
	
	inline void cut(int u, int v) {
		make_root(u); access(v); splay(u);
		ns[u].rs = 0, ns[v].fa = 0;
		update(u);
	}
	
	inline void change_add(int u, int v, int c) {
		make_root(u); access(v); splay(v);
		make_add(v, c);
	} 
	
	inline void change_mul(int u, int v, int c) {
		make_root(u); access(v); splay(v);
		make_mul(v, c);
	}
	
	inline int query(int u, int v) {
		make_root(u); access(v); splay(v);
		return ns[v].sum;
	}

}lct;

inline int get_num() {
	int ans = 0;
	char tmp = getchar();
	while(tmp < '0' || tmp > '9') tmp = getchar();
	while(tmp >= '0' && tmp <= '9') {
		ans = ans*10 + tmp - '0';
		tmp = getchar(); 
	}
	return ans;
}

inline char get_han() {
	char tmp = getchar();
	while(tmp != '*' && tmp != '/' && tmp != '+' && tmp != '-') tmp = getchar();
	return tmp;
} 

int n, q;

inline void read() {
	n = get_num(); q = get_num();
	int u, v;
	for(int i = 1; i <= n-1; i++) {
		u = get_num(), v = get_num();
		lct.link(u, v);
	}
}

inline void solve() {
	char han;
	int u, v, c;
	for(int i = 1; i <= q; i++) {
		han = get_han();
		if(han == '+') {
			u = get_num(), v = get_num(), c = get_num();
			lct.change_add(u, v, c);
		} else if(han == '-') {
			u = get_num(), v = get_num();
			lct.cut(u, v);
			u = get_num(), v = get_num();
			lct.link(u, v);
		} else if(han == '*') {
			u = get_num(), v = get_num(), c = get_num();
			lct.change_mul(u, v, c); 
		} else if(han == '/') {
			u = get_num(), v = get_num(), c = lct.query(u, v);
			printf("%d\n", c);
		}
	}
}

int main() {
	freopen("nt2012_wym_tree.in", "r", stdin);
	freopen("nt2012_wym_tree.out", "w", stdout);
	read();
	solve();
	return 0;
}