您的位置:首页 > 其它

URAL 1553 Caves and Tunnels(LCT动态树)

2017-01-18 08:22 162 查看
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 ≤ ai, bi ≤ 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 ≤ U, V ≤ 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: