#include<cstdio>
#include<cstring>
#include<vector>
#include<istream>
#define ls u<<1,l,mid
#define rs u<<1|1,mid+1,r
#define maxn 100020
#define ll long long
using namespace std;
int n,m,head[2*maxn],hz[maxn],top[maxn],size[maxn],tot=1,cur[maxn],nu[maxn],vis[maxn],f[maxn],cnt,d[maxn];
struct edge{
int v,next;
}e[maxn*2];
void adde(int a,int b){
e[tot].v=b;
e[tot].next=head[a];
head[a]=tot++;
}
void dfs1(int u,int fa){
size[u]=1;hz[u]=0,f[u]=fa,d[u]=d[fa]+1;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].v;
if(v==fa)continue;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>size[hz[u]])hz[u]=v;
}
}
void dfs2(int u,int front){
vis[u]=1;nu[u]=++cnt,top[u]=front;
if(hz[u])dfs2(hz[u],front);
for(int i=head[u];~i;i=e[i].next){
int v=e[i].v;
if(vis[v])continue;
dfs2(v,v);
}
}
struct node{
int l,r;ll Max;
}nod[maxn*4];
void push_up(int u){nod[u].Max=max(nod[u<<1].Max,nod[u<<1|1].Max);}
void build(int u,int l,int r){
nod[u].l=l,nod[u].r=r;
if(l==r){
nod[u].Max=0;return;
}
int mid=l+r>>1;
build(rs);build(ls);
push_up(u);
}
void update(int u,int l,int r,int x,ll add){
if(l==r){
nod[u].Max+=add;
return;
}
int mid=l+r>>1;
if(x>mid)update(rs,x,add);
else update(ls,x,add);
push_up(u);
}
ll query(int u,int l,int r,int x,int y){
if(l==x&&r==y)return nod[u].Max;
int mid=l+r>>1;
if(x>mid)return query(rs,x,y);
else if(y<=mid)return query(ls,x,y);
else return max(query(ls,x,mid),query(rs,mid+1,y));
}
ll qmax(int a,int b){
ll ans=-1e14;
if(d[top[a]]>d[top[b]])swap(a,b);
while(top[a]!=top[b]){
if(d[top[a]]>d[top[b]]){
ans=max(ans,query(1,1,cnt,nu[top[a]],nu[a]));
a=f[top[a]];
}else{
ans=max(ans,query(1,1,cnt,nu[top[b]],nu[b]));
b=f[top[b]];
}
}
if(a!=b){
if(nu[a]<nu[b])ans=max(ans,query(1,1,cnt,nu[a],nu[b]));
else ans=max(ans,query(1,1,cnt,nu[b],nu[a]));
}
if(a==b)ans=max(ans,query(1,1,cnt,nu[a],nu[a]));
return ans;
}
int main(){
freopen("A.in","r",stdin);
freopen("A.out","w",stdout);
memset(head,-1,sizeof(head));
scanf("%d",&n);
for(int a,b,i=1;i<n;i++){
scanf("%d%d",&a,&b);
adde(a,b);
adde(b,a);
}
dfs1(1,1);
dfs2(1,1);
build(1,1,cnt);
scanf("%d",&m);
char s[4];
int a;
while(m--){
scanf("%s",s);
if(s[0]=='I'){
ll b;
scanf("%d%I64d",&a,&b);
update(1,1,cnt,nu[a],b);
}else if(s[0]=='G'){
int b;
scanf("%d%d",&a,&b);
printf("%I64d\n",qmax(a,b));
}
}
return 0;
}/*
10
1 2
2 4
4 6
4 7
6 10
1 3
3 8
3 5
5 9
*/
树链剖分模板
最新推荐文章于 2021-07-25 17:09:52 发布