URAL 1553 Caves and Tunnels(LCT動態樹)

After landing on Mars surface, scientists found a strange system of caves connected bytunnels. So they began to research it using remote controlled robots. It was found out that there exists exactly one route between every pair of caves. But then scientists faced aparticular problem. Sometimes in the caves faint explosions happen. They cause emissionof radioactive isotopes and increase radiation level in the cave. Unfortunately robotsdon't stand radiation well. But for the research purposes they must travel from one caveto another. So scientists placed sensors in every cave to monitor radiation level in thecaves. And now every time they move robots they want to know the maximal radiation levelthe robot will have to face during its relocation. So they asked you to write a program thatwill solve their problem.

Input

The first line of the input contains one integer N (1 ≤ N ≤ 100000) — the number of caves. Next N − 1 lines describe tunnels. Each of these lines contains a pair of integersai,bi (1 ≤ aibi ≤ N)specifying the numbers of the caves connected by corresponding tunnel. The next line has an integerQ(Q ≤ 100000) representing the number of queries. TheQ queries follow on a single line each. Every query hasa form of "C U V", whereC is a single character and can be either 'I' or 'G' representing the type of the query (quotesfor clarity only). In the case of an 'I' query radiation level inU-th cave (1 ≤ U ≤ N) is incremented byV (0 ≤ V ≤ 10000).In the case of a 'G' query your program must output the maximal level of radiation on the way between caves withnumbersU andV (1 ≤ UV ≤ N) after all increases of radiation ('I' queries) specified before current query.It is assumed that initially radiation level is 0 in all caves, and it never decreases with time (because isotopes'half-life time is much larger than the time of observations).

Output

For every 'G' query output one line containing the maximal radiation level by itself.

Sample

input output
4
1 2
2 3
2 4
6
I 1 1
G 1 1
G 3 4
I 2 3
G 1 1
G 3 4 
1
0
1
3
題意:一棵樹 開始每個點的權值都爲0
2種操作     1.將第i個點的權值增加x 2.求u到v這條路上最大的權值

LCT做法:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define F(x) tree[x].fa
#define LC(x) tree[x].child[0]
#define RC(x) tree[x].child[1]
#define REV(x) tree[x].rev
#define Size 300010
using namespace std;
inline int read(){
	int sum=0,fg=1;char c=getchar();
	while(c<'0' || c>'9'){if(c=='-')fg=-1;c=getchar();}
	while(c>='0' && c<='9'){sum=sum*10+c-'0';c=getchar();}
	return sum*fg;
}
struct lct{
	int fa,child[2],rev;
	int v,MAX;
}tree[Size];
int be[Size],ne[Size],to[Size],e;
struct link_cut_tree{
	inline bool isroot(int x){
		return LC(F(x))!=x && RC(F(x))!=x;
	}
	inline void increase(int x,int val){
		tree[x].v+=val;tree[x].MAX+=val;
	}
	inline void pushup(int x){
		tree[x].MAX=max(tree[LC(x)].MAX,tree[RC(x)].MAX);
		tree[x].MAX=max(tree[x].MAX,tree[x].v);
	}
	inline void pushdown(int x){
		if(REV(x)){
			REV(x)^=1;REV(LC(x))^=1;REV(RC(x))^=1;
			swap(LC(x),RC(x));
		}
	}
	void Pushdown(int x){
		if(!isroot(x))Pushdown(F(x));
		pushdown(x);
	}
	inline void rotate(int x){
		int A=F(x),B=F(A);bool w=(RC(A)==x);
		if(!isroot(A)){
			if(LC(B)==A)LC(B)=x;
			else if(RC(B)==A)RC(B)=x;
		}
		F(tree[x].child[w^1])=A;F(A)=x;F(x)=B;
		tree[A].child[w]=tree[x].child[w^1];tree[x].child[w^1]=A;
		pushup(A);pushup(x);
	}
	inline void splay(int x){
		Pushdown(x);
		while(!isroot(x)){
			if(!isroot(F(x)))rotate(x);
			rotate(x);
		}
	}
	inline void access(int x){
		for(int i=0;x;i=x,x=F(x))splay(x),RC(x)=i,pushup(x);
	}
	inline int find_root(int x){
		access(x);splay(x);while(LC(x))x=LC(x);
		return x;
	}
	inline void reverse(int x){
		access(x);splay(x);REV(x)^=1;
	}
	inline void link(int x,int y){
		reverse(x);F(x)=y;
	}
	inline void cut(int x,int y){
		reverse(x);access(y);splay(y);
		F(LC(y))=0;LC(y)=0;pushup(y);
	}
	inline void add(int x,int val){
		splay(x);
		increase(x,val);
		pushup(x);
	}
	inline int query(int x,int y){
		reverse(x);access(y);splay(y);
		return tree[y].MAX;
	}
}LCT;
int main(){
	int n;
	while(scanf("%d",&n)!=EOF){
		for(int i=1;i<n;i++){
			int x=read(),y=read();
			LCT.link(x,y);
		}
		int m=read();
		while(m--){
			char tp[10];
			scanf("%s",tp);
			if(tp[0]=='I'){
				int x=read(),val=read();
				LCT.add(x,val);
			}
			else{
				int x=read(),y=read();
				printf("%d\n",LCT.query(x,y));
			}
		}
	}
	return 0;
}



發佈了83 篇原創文章 · 獲贊 27 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章