【BZOJ 1036】【ZJOI 2008】树的统计Count

http://www.lydsy.com/JudgeOnline/problem.php?id=1036
复习了一下好写好调的lct模板啦啦啦~~~

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 30003;

int n;
struct node *null;
struct node {
	node *fa, *ch[2];
	int w, sum, ma, rev;
	bool pl() {return fa->ch[1] == this;}
	bool check() {return fa == null || (fa->ch[0] != this && fa->ch[1] != this);}
	void setc(node *r, int c) {ch[c] = r; if (r != null) r->fa = this;}
	void count() {
		sum = ch[0]->sum + ch[1]->sum + w;
		ma = w;
		if (ch[0] != null) ma = max(ma, ch[0]->ma);
		if (ch[1] != null) ma = max(ma, ch[1]->ma);
	}
	void push() {if (rev) {swap(ch[0], ch[1]); rev = 0; ch[0]->rev ^= 1; ch[1]->rev ^= 1;}}
} pool[N];

namespace LCT {
	void rotate(node *r) {
		node *f = r->fa;
		int c = r->pl();
		if (f->check()) r->fa = f->fa;
		else f->fa->setc(r, f->pl());
		f->setc(r->ch[c ^ 1], c);
		r->setc(f, c ^ 1);
		f->count();
	}
	
	void update(node *r) {if (!r->check()) update(r->fa); r->push();}
	
	void splay(node *r) {
		update(r);
		for (; !r->check(); rotate(r))
			if (!r->fa->check()) rotate(r->pl() == r->fa->pl() ? r->fa : r);
		r->count();
	}
	
	node *access(node *r) {
		node *y = null;
		while (r != null) {
			splay(r);
			r->ch[1] = y;
			y = r; r = r->fa;
		}
		return y;
	}
	
	void changeroot(node *r) {access(r)->rev ^= 1; splay(r);}
	void link(node *r, node *t) {changeroot(r); r->fa = t;}
	int query_max(node *u, node *v) {changeroot(u); access(v); splay(v); return v->ma;}
	int query_sum(node *u, node *v) {changeroot(u); access(v); splay(v); return v->sum;}
	
	int x[N], y[N];
	void init() {
		null = &pool[0];
		null->fa = null->ch[0] = null->ch[1] = null;
		null->ma = null->sum = null->rev = null->w = 0;
		
		scanf("%d", &n);
		for (int i = 1; i < n; ++i) scanf("%d%d", x + i, y + i);
		for (int i = 1; i <= n; ++i) {
			pool[i].fa = pool[i].ch[0] = pool[i].ch[1] = null;
			pool[i].rev = 0;
			scanf("%d", &pool[i].w);
			pool[i].ma = pool[i].sum = pool[i].w;
		}
		
		for (int i = 1; i < n; ++i) link(&pool[x[i]], &pool[y[i]]);
	}
}

int main() {
	LCT::init();
	
	int q, u, v;
	char s[18];
	scanf("%d", &q);
	while (q--) {
		scanf("%s%d%d", s, &u, &v);
		if (s[0] == 'C') {
			LCT::splay(&pool[u]);
			pool[u].w = pool[u].ma = pool[u].sum = v;
		} else {
			if (s[1] == 'M') printf("%d\n", LCT::query_max(&pool[u], &pool[v]));
			else printf("%d\n", LCT::query_sum(&pool[u], &pool[v]));
		}
	}
	return 0;
}
posted @ 2017-02-01 21:37  abclzr  阅读(201)  评论(0编辑  收藏  举报