#P10067. 洪水
洪水
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define MAXN 200005
#define MAXM 400005
#define INF 0x7fffffff
using namespace std ;
typedef long long LL ;
struct road {
LL x, next ;
} r[MAXM] ;
// (1) sigma(dp[son[x]]) > p[x] ;
// (2) sigma(dp[son[x]]) <= p[x] ;
// d[x] = sigma(dp[son[x]])-p[x] ;
// d[x]>0 -> (1), d[x]<=0 -> (2)
LL N, M, Q ;
LL son[MAXN][2], fa[MAXN], par[MAXN] ;
LL sum[MAXN], mx[MAXN], d[MAXN] ;
LL p[MAXN], up[MAXN], spe[MAXN] ;
LL st[MAXN], w ;
void add(LL x, LL y)
{
r[++w].x = y, r[w].next = st[x] ;
st[x] = w ;
}
void Update(LL x)
{
mx[x] = max(d[x], max(mx[son[x][0]], mx[son[x][1]])) ;
}
void Maintain(LL x, LL c)
{
sum[x] += c, d[x] += c, mx[x] += c ;
}
void Push_down(LL x)
{
if(sum[x])
{
if(son[x][0]) Maintain(son[x][0], sum[x]) ;
if(son[x][1]) Maintain(son[x][1], sum[x]) ;
sum[x] = 0 ;
}
}
void Rotate(LL x, LL d)
{
LL tmp = fa[x] ;
par[x] = par[tmp], par[tmp] = 0 ;
son[tmp][d^1] = son[x][d], fa[son[x][d]] = tmp ;
if(fa[tmp]) son[fa[tmp]][son[fa[tmp]][1]==tmp] = x ;
fa[x] = fa[tmp], fa[tmp] = x, son[x][d] = tmp ;
Update(tmp), Update(x) ;
}
void Splay(LL x, LL to)
{
LL i, tmp, d1, d2 ;
Push_down(x) ;
while((tmp=fa[x]) != to)
{
if(fa[tmp]) Push_down(fa[tmp]) ;
Push_down(tmp), Push_down(x) ;
if(fa[tmp] == to)
Rotate(x, son[tmp][0] == x) ;
else if((d1=(son[tmp][0]==x)) == (d2=(son[fa[tmp]][0]==tmp)))
Rotate(tmp, d2), Rotate(x, d1) ;
else Rotate(x, d1), Rotate(x, d2) ;
}
}
void Split(LL x)
{
Splay(x, 0) ;
if(son[x][1]) par[son[x][1]] = x, fa[son[x][1]] = 0, son[x][1] = 0 ;
Update(x) ;
}
void Merge(LL x, LL y)
{
Splay(x, 0), Splay(y, 0) ;
par[y] = 0, fa[y] = x, son[x][1] = y ;
}
LL Access(LL x)
{
LL i, tmp = x ;
Split(x) ;
for(x = par[x]; x; tmp = x, x = par[x])
Split(x), Merge(x, tmp) ;
return tmp ;
}
LL Find(LL x, LL t)
{
LL i, tmp ;
while(x)
{
tmp = x ;
Push_down(x) ;
if(mx[son[x][1]] > t)
x = son[x][1] ;
else if(d[x] > t) return x ;
else x = son[x][0] ;
}
return tmp ;
}
void Work(LL x, LL c)
{
LL tmp, i ;
Access(x), Splay(x, 0) ;
if((tmp=up[x]) != 0)
Access(tmp) ;
if(!spe[x])
{
d[x] -= c ;
if(d[x]+c <= 0) return ;
if(d[x] <= 0) c = d[x]+c ;
}
// dp[x] => dp[x]+c
x = tmp ;
while(x)
{
Splay(x, 0) ;
tmp = Find(x, -c) ;
Splay(tmp, 0) ;
if(son[tmp][1]) Maintain(son[tmp][1], c) ;
d[tmp] += c, Update(tmp) ;
if(tmp == 1 || d[tmp]-c >= 0) return ;
c = c-d[tmp] ;
Split(up[tmp]), x = up[tmp] ;
}
}
int f1, r1 ;
int q[MAXN], vis[MAXN] ;
void Build()
{
LL i, x, tmp ;
q[++r1] = 1 ;
while(f1 < r1)
{
x = q[++f1], vis[x] = 1 ;
for(i = st[x]; i; i = r[i].next)
if(!vis[tmp=r[i].x])
{
vis[x] ++ ;
up[tmp] = par[tmp] = x ;
q[++r1] = tmp ;
}
}
for(i = N; i >= 1; i --)
{
x = q[i] ;
if(vis[x] == 1) mx[x] = 0, spe[x] = 1 ;
else mx[x] = d[x] = d[x]-p[x] ;
if(up[x]) d[up[x]] += p[x]+min(0LL, d[x]) ;
}
}
LL ks, ans ;
char in[10], out[10], ss[10] ;
int main()
{
LL i, j ;
LL fr, to ;
mx[0] = -INF ;
scanf("%lld", &N) ;
for(i = 1; i <= N; i ++)
scanf("%lld", &p[i]) ;
for(i = 1; i < N; i ++)
{
scanf("%I64d %I64d", &fr, &to) ;
add(fr, to), add(to, fr) ;
}
Build() ;
scanf("%lld", &Q) ;
for(i = 1; i <= Q; i ++)
{
scanf("%s %lld", ss, &fr) ;
if(fr == 17 || fr == 35 || fr == 36 || fr == 38 || fr == 45)
i ++, i -- ;
if(i == 46)
i ++, i -- ;
if(ss[0] == 'C')
{
scanf("%lld", &to) ;
p[fr] += to, Work(fr, to) ;
}
else
{
Access(fr), Splay(fr, 0) ;
if(!r[st[fr]].next) printf("%lld\n", p[fr]) ;
else printf("%lld\n", ans=p[fr]+min(0LL, d[fr])) ;
}
}
//system("pause") ;
return 0 ;
}