URAL 1553 Caves and Tunnels(LCT动态树)

科学家使用遥控机器人探索火星上相连的洞穴系统时遇到挑战。由于洞穴中偶尔发生的爆炸会提高辐射水平,需要编写程序来监测机器人在不同洞穴间移动时的最大辐射暴露值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

inputoutput
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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值