hdu 4010 Lct动态链接树

#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include <cstdio>
#include <memory>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <cassert>
#include <string>
#include <ctime>
#include <map>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <set>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define req(i,a,b) for(int i=a;i>=b;i--)
#define rp(i,a) for(int i=head[a];i+1;i=edge[i].next)
#define cl(a,b) memset(a,b,sizeof a);
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mod 10007
const int inf = ~0u >> 2;
const ll INF = (1LL << 62) - 1;
double eps = 1e-12;
const int N = 300005 + 5;
const int M = 300005;


int n, m, d;

class Lct {
public:
	Lct() {}
	~Lct() {}
	struct Node {
		int value, size, add, reverse, mx;
		Node *parent, *child[2];
	}_nil, *node[N];
public:
	void Init() {
		nil = new Node;
		nil->child[0] = nil->child[1] = nil;
		nil->size = 0;
		nil->parent = nil;
		nil->mx = -(inf << 1) - 2;
		nil->add = 0;
		nil->value = -(inf << 1) - 2;
		nil->reverse = 0;
		Root = nil;
		//nil->
		//Insert(-(inf<<1)-2);
		//Insert((inf<<1)+1);
		//Insert(0);
		//Insert(n + 1);
	}
	bool IsRoot(Node *x) {
		if (x == nil)
			return true;
		if (x->parent->child[0] == x || x->parent->child[1] == x)
			return false;
		return true;
	}
	void update(Node *x) {
		/*if (x == nil)
			return;*/
		x->mx = max(x->value, max(x->child[0]->mx, x->child[1]->mx));
		//x->size = x->child[0]->size + x->child[1]->size + 1;
	}
	void down(Node *x) {
		if (x == nil)return;
		if (x->reverse) {
			if (x->child[0] != nil) {
				x->child[0]->reverse ^= 1;
			}
			if (x->child[1] != nil) {
				x->child[1]->reverse ^= 1;
			}
			swap(x->child[0], x->child[1]);
			x->reverse = 0;
		}
		if (x->add) {
			if (x->child[0] != nil) {
				x->child[0]->value += x->add;
				x->child[0]->mx += x->add;
				x->child[0]->add += x->add;
			}
			if (x->child[1] != nil) {
				x->child[1]->value += x->add;
				x->child[1]->mx += x->add;
				x->child[1]->add += x->add;
			}
			x->add = 0;
		}
	}
	void Rotate(Node *x, int dir) {
		if (IsRoot(x))return;
		Node * p = x->parent;
		if (p->parent->child[0] == p)
		{
			p->parent->child[0] = x;
		}
		else if (p->parent->child[1] == p) {
			p->parent->child[1] = x;
		}
		x->parent = p->parent;
		p->child[dir ^ 1] = x->child[dir];
		p->child[dir ^ 1]->parent = p;
		x->child[dir] = p;
		p->parent = x;
		update(p);
		update(x);
		/*if (Root == p) {
		Root = x;
		}*/
	}
	void Splay(Node *x) {
		static Node *sta[N];
		int top = 0;
		sta[top++] = x;
		for (Node *y = x; !IsRoot(y); y = y->parent)
			sta[top++] = y->parent;
		while (top)down(sta[--top]);
		while (!IsRoot(x)) {
			if (IsRoot(x->parent)) {
				if (x->parent->child[0] == x) {
					Rotate(x, 1);
				}
				else {
					Rotate(x, 0);
				}
			}
			else if (x->parent->parent->child[0] == x->parent) {
				if (x->parent->child[0] == x) {
					Rotate(x->parent, 1);
					Rotate(x, 1);
				}
				else {
					Rotate(x, 0);
					Rotate(x, 1);
				}
			}
			else {
				if (x->parent->child[1] == x) {
					Rotate(x->parent, 0);
					Rotate(x, 0);
				}
				else {
					Rotate(x, 1);
					Rotate(x, 0);
				}
			}
			update(x);
		}
	}
	Node *NewNode(Node *x, int val) {
		x = new Node;
		x->parent = nil;
		x->value = val;
		x->size = 1;
		x->add = 0;
		x->mx = val;
		x->reverse = 0;
		x->child[0] = x->child[1] = nil;
		return x;
	}
	void dfs(Node *u) {
		if (u->child[0] != nil)
			dfs(u->child[0]);
		printf(" %d", u->value);
		if (u->child[1] != nil)
			dfs(u->child[1]);
	}
	//void Insert(int u,int val){
	//	if (Root == nil) {
	//		Root = NewNode(nil, val);
	//		return;
	//	}
	//	Node *x=Root;
	//	while (x->child[val>=x->value]!=nil) {
	//		x = x->child[val>=x->value];
	//	}
	//	Node *t = NewNode(x,val);
	//	node[u] = t;
	//	x->child[val >= x->value] = t;
	//	update(x);
	//	Splay(t, nil);
	///*	printf("dfs:");
	//	dfs(Root);
	//	printf("
");*/
	//}
	//void Remove(int val) {
	//	int rnk = FindValRank(val);
	//	FindRankTo(rnk - 1, nil);
	//	FindRankTo(rnk + 1, Root);
	//	Root->child[1]->child[0] = nil;
	//	update(Root->child[1]);
	//	update(Root);
	//}
	//int FindValRank(int val) {
	//	Node *x = Root;
	//	int sum = 0;
	//	while (x->child[val >= x->value]!=nil) {
	//		if (x->value == val)
	//			return sum + 1 + x->child[0]->size;
	//		if (val >= x->value) {
	//			sum += x->child[0]->size+1;
	//		}
	//		x = x->child[val >= x->value];
	//	}
	//	return sum+1+x->child[0]->size;
	//}
	//void FindRankTo(int rnk, Node *y) {
	//	Node *x = Root;
	//	while (x!=nil) {
	//		if (rnk == x->child[0]->size+1)
	//		{
	//			Splay(x, y);
	//			return;
	//		}
	//		if (rnk > x->child[0]->size) {
	//			rnk -= x->child[0]->size + 1;
	//			x = x->child[1];
	//		}
	//		else
	//			x = x->child[0];
	//	}
	//}
	//int FindRoot(int x) {

	//}
	/*int FindRankVal(int k) {
	FindRankTo(k, nil);
	return Root->value;
	}*/
	Node *Access(Node *x) {
		Node *y = x;
		x = nil;
		while (y != nil) {
			Splay(y);
			//y->child[1]->parent = y;
			y->child[1] = x;
			x->parent = y;
			update(y);
			x = y;
			y = y->parent;
		}
		return x;
	}
	//Node *FindRoot(Node *x) {
	//	Access(x);
	//	Splay(x);
	//	while (x->child[0] != nil)x = x->child[0];
	//	Splay(x);
	//	return x;
	//}
	void Cut(Node *x) {
		//ChangeRoot(x->parent);
		/*Access(x);
		Splay(x);
		x->reverse ^= 1;*/
		ChangeRoot(x);
		x->child[0]->parent = nil;
		x->child[0] = nil;
		update(x);
	}
	void Link(Node *x, Node *y) {
		//printf("%d %d#
", x->value, y->value);
		/*Access(x);
		Splay(x);
		x->reverse ^= 1;*/
		ChangeRoot(x);
		x->parent = y;
		//Access(x);
		//
	}
	void ChangeRoot(Node *x) {
		Access(x);
		Splay(x);
		x->reverse ^= 1;
	}
	void AddVal(Node *x, Node *y, int val) {
		ChangeRoot(y);
		ChangeRoot(x);
		//Node *u = Access(x);
		//Node *u = BecomeRoot(x);
		/*Cut(y->child[1]);
		while (y->child[0] != x)y = y->child[0];
		Cut(x->child[0]);*/
		//Access(x);
		x->value += val;
		x->add += val;
		x->mx += val;
	}
	int QueryMaxVal(Node *x, Node *y) {
		ChangeRoot(y);
		ChangeRoot(x);
		//Node *u = Access(x);
		//BecomeRoot(x);
		return x->mx;
		/*Cut(y->child[1]);
		while(y->child[0])*/
	}
	bool IsSameTree(Node *u, Node *v) {
		while (u->parent != nil)u = u->parent;
		while (v->parent != nil)v = v->parent;
		return u == v;
	}
public:
	int w[N];
	Node *Root, *nil;
};
struct Seg {
	int l, r, k, index;
	bool operator < (const Seg & rhs)const {
		return r < rhs.r;
	}
}seg[M];
Lct lct;
//SplayTree spt;
int ans[M];
void printErr() {
	printf("-1
");
}
int nd1[N], nd2[N];
int main() {
	int n;
	while (scanf("%d",&n)!=-1) {
		lct.Init();
		for (int i = 1; i < n; i++) {
			int u, v;
			scanf("%d%d", &u, &v);
			//g[u].push_back(v);
			nd1[i] = u;
			nd2[i] = v;
		}
		for (int i = 1; i <= n; i++) {
			scanf("%d", &lct.w[i]);
			lct.node[i] = lct.NewNode(lct.node[i], lct.w[i]);
		}
		for (int i = 1; i < n; i++)
			lct.Link(lct.node[nd1[i]], lct.node[nd2[i]]);
		/*for (int i = 1; i <= n; i++)
			for (int j = 0; j < g[i].size(); j++)
				lct.Link(lct.node[i], lct.node[g[i][j]]);*/
				//for (int i = 1; i <= n; i++) {
				//	if (lct.IsRoot(lct.node[i])) {
				//		printf("Root :%d", i);
				//		lct.dfs(lct.node[i]);
				//		printf("
");
				//	}
				//}
		scanf("%d", &m);
		while (m--) {
			int op;
			scanf("%d", &op);
			if (op == 1) {
				int x, y;
				scanf("%d%d", &x, &y);
				if (lct.IsSameTree(lct.node[x], lct.node[y])) {
					printErr();
					continue;
				}
				lct.Link(lct.node[x], lct.node[y]);
			}
			if (op == 2) {
				int x, y;
				scanf("%d%d", &x, &y);
				if (x==y||!lct.IsSameTree(lct.node[x], lct.node[y])) {
					printErr();
					continue;
				}
				lct.ChangeRoot(lct.node[x]);
				lct.Cut(lct.node[y]);
			}
			if (op == 3) {
				int w, x, y;
				scanf("%d%d%d", &w, &x, &y);
				if (!lct.IsSameTree(lct.node[x], lct.node[y])) {
					printErr();
					continue;
				}
				lct.AddVal(lct.node[x], lct.node[y], w);
			}
			if (op == 4) {
				int x, y;
				scanf("%d%d", &x, &y);
				if (!lct.IsSameTree(lct.node[x], lct.node[y])) {
					printErr();
					continue;
				}
				printf("%d
", lct.QueryMaxVal(lct.node[x], lct.node[y]));
			}
		}
		printf("
");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/HaibaraAi/p/6368685.html