zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    PHP环境搭建-修改密码
    先挖个坑....
    usaco 1.2.1(指针技巧)
    warfare(最大生成树裸题)
    最大生成树(最小生成树同理)
    快排
    简单邻接表代码实现
    并查集模板题
    并查集
    get 新技能
  • 原文地址:https://www.cnblogs.com/HaibaraAi/p/6368685.html
Copyright © 2011-2022 走看看