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