# 【bzoj4712】洪水 树链剖分+线段树维护树形动态dp

n<=200000，保证任意to都为非负数

4
4 3 2 1
1 2
1 3
4 2
4
Q 1
Q 2
C 4 10
Q 1

3
1
4

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 200010
#define lson l , mid , x << 1
#define rson mid + 1 , r , x << 1 | 1
using namespace std;
typedef long long ll;
struct data
{
ll sum , ls;
data() {}
data(ll g , ll v) {sum = g , ls = v;}
inline data operator+(const data &a)const
{
return data(sum + a.sum , min(sum + a.ls , ls));
}
}a[N << 2] , w[N];
int head[N] , to[N << 1] , next[N << 1] , cnt , fa[N] , si[N] , bl[N] , end[N] , pos[N] , tot , n;
ll v[N] , f[N] , g[N];
char str[5];
inline void add(int x , int y)
{
}
void dfs1(int x)
{
int i;
si[x] = 1;
for(i = head[x] ; i ; i = next[i])
if(to[i] != fa[x])
fa[to[i]] = x , dfs1(to[i]) , si[x] += si[to[i]];
}
void dfs2(int x , int c)
{
int i , k = 0;
bl[x] = c , pos[x] = ++tot , end[x] = x , f[x] = v[x];
for(i = head[x] ; i ; i = next[i])
if(to[i] != fa[x] && si[to[i]] > si[k])
k = to[i];
if(k)
{
dfs2(k , c) , end[x] = end[k];
for(i = head[x] ; i ; i = next[i])
if(to[i] != fa[x] && to[i] != k)
dfs2(to[i] , to[i]) , g[x] += f[to[i]];
f[x] = min(f[x] , f[k] + g[x]);
}
w[pos[x]] = data(g[x] , v[x]);
}
inline void pushup(int x)
{
a[x] = a[x << 1] + a[x << 1 | 1];
}
void build(int l , int r , int x)
{
if(l == r)
{
a[x] = w[l];
return;
}
int mid = (l + r) >> 1;
build(lson) , build(rson);
pushup(x);
}
void updatev(int p , ll v , int l , int r , int x)
{
if(l == r)
{
a[x].ls += v;
return;
}
int mid = (l + r) >> 1;
if(p <= mid) updatev(p , v , lson);
else updatev(p , v , rson);
pushup(x);
}
void updateg(int p , ll g , int l , int r , int x)
{
if(l == r)
{
a[x].sum += g;
return;
}
int mid = (l + r) >> 1;
if(p <= mid) updateg(p , g , lson);
else updateg(p , g , rson);
pushup(x);
}
data query(int b , int e , int l , int r , int x)
{
if(b <= l && r <= e) return a[x];
int mid = (l + r) >> 1;
if(e <= mid) return query(b , e , lson);
else if(b > mid) return query(b , e , rson);
else return query(b , e , lson) + query(b , e , rson);
}
inline void modify(int x , ll v)
{
int y = x;
ll t;
while(x)
{
t = query(pos[bl[x]] , pos[end[x]] , 1 , n , 1).ls;
if(x == y) updatev(pos[x] , v , 1 , n , 1);
else updateg(pos[x] , v , 1 , n , 1);
v = query(pos[bl[x]] , pos[end[x]] , 1 , n , 1).ls - t , x = fa[bl[x]];
}
}
int main()
{
int m , i , x , y;
ll z;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ ) scanf("%lld" , &v[i]);
for(i = 1 ; i < n ; i ++ ) scanf("%d%d" , &x , &y) , add(x , y) , add(y , x);
dfs1(1) , dfs2(1 , 1);
build(1 , n , 1);
scanf("%d" , &m);
while(m -- )
{
scanf("%s%d" , str , &x);
if(str[0] == 'C') scanf("%lld" , &z) , modify(x , z);
else printf("%lld\n" , query(pos[x] , pos[end[x]] , 1 , n , 1).ls);
}
return 0;
}


posted @ 2018-04-03 19:04  GXZlegend  阅读(899)  评论(0编辑  收藏