Orz
\color{green}\text{Orz}
Orz
stO
\color{red}\text{stO}
stO
stO
Orz
\color{red}\text{stO} \color{orange}\text{}\color{green}\text{Orz}
stOOrz
stO
树链剖分
Orz
\color{red}\text{stO} \color{orange}\text{树链剖分}\color{green}\text{Orz}
stO树链剖分Orz
stO
树的统计
Orz
\color{red}\text{stO} \color{orange}\text{树的统计}\color{green}\text{Orz}
stO树的统计Orz
stO
我的存档
Orz
\color{red}\text{stO} \color{orange}\text{我的存档}\color{green}\text{Orz}
stO我的存档Orz
stO
code
Orz
\color{red}\text{stO} \color{orange}\text{code}\color{green}\text{Orz}
stOcodeOrz
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <algorithm>
#define N 200010
using namespace std ;
int n , m , p ;
struct Edge{
int x , y , z , next ;
}a[N] ;
struct Tree{
int lc , rc , sum , tag , maxn ;
}tree[N] ;
int add_tot ;
int w[N] , wt[N] ;
int son[N] , l[N] , fa[N] , cnt , dep[N] , size[N] , top[N] ;
int res = 0 ;int t = 0 , head[N] , ans ;
void pushup (int u ) {
tree[u].sum = tree[tree[u].lc].sum + tree[tree[u].rc].sum ;
tree[u].maxn = max(tree[tree[u].lc].maxn,tree[tree[u].rc].maxn) ;
return ;
}
void pushdown(int u , int l , int r) {
int mid = (l+r) >> 1 ;
tree[tree[u].lc].sum += tree[u].tag * (mid-l+1) ;
tree[tree[u].lc].tag += tree[u].tag ;
tree[tree[u].rc].sum += tree[u].tag * (r-mid) ;
tree[tree[u].rc].tag += tree[u].tag ;
tree[u].tag = 0 ;
}
void update(int u ,int l ,int r,int ll ,int rr ,int w) {
if(l == ll && r == rr) {
tree[u].sum += (r-l+1)*w ;
tree[u].tag += w ;
return ;
}
int mid = (l+r) >> 1 ;
pushdown(u,l,r) ;
if(rr <= mid) update(tree[u].lc , l,mid,ll,rr,w) ;
else if(ll > mid) update(tree[u].rc,mid+1,r,ll,rr,w) ;
else {
update(tree[u].lc,l,mid,ll,mid,w) ;
update(tree[u].rc,mid+1,r,mid+1,rr,w) ;
}
pushup(u) ;
}
int query(int u ,int l ,int r,int ll,int rr) {
if(l == ll && r == rr) {
return tree[u].sum ;
}int mid = (l+r) >>1 ;
pushdown(u,l,r) ;
if(rr <= mid) return query(tree[u].lc,l,mid,ll,rr) ;
else if(ll > mid) return query(tree[u].rc,mid+1,r,ll,rr) ;
else {
return (query(tree[u].lc,l,mid,ll,mid)+query(tree[u].rc,mid+1,r,mid+1,rr)) ;
}
pushup(u) ;
}
int tt = 1 ;
void add(int x , int y) {
a[++add_tot].x = x ;
a[add_tot].y = y ;
a[add_tot].next = head[x] ;
head[x] = add_tot ;
}
int qmax(int u,int l,int r,int ll,int rr) {
if(l == ll && r == rr){
res = tree[u].maxn ;
return res ;
}
int mid = (l+r) >> 1 ;
pushdown(u,l,r) ;
if(rr <= mid) return qmax(tree[u].lc,l,mid,ll,rr ) ;
else if(ll > mid) return qmax(tree[u].rc,mid+1,r,ll,rr) ;
else{
return max(qmax(tree[u].lc,l,mid,ll,mid) , qmax(tree[u].rc,mid+1,r,mid+1,rr) ) ;
}
}
void build (int u , int l ,int r) {
if(l == r) {
tree[u].sum = wt[l] ;
tree[u].maxn = wt[l] ;
return ;
}
int mid = (l+r) >> 1 ;
tree[u].lc = ++tt ;
build(tree[u].lc,l,mid) ;
tree[u].rc = ++tt ;
build(tree[u].rc,mid+1,r) ;
pushup(u) ;
}
int qrange(int x,int y) {
int ans = 0 ;
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]] ) {
swap(x,y) ;
}
ans += query(1,1,n,l[top[x]],l[x]) ;
x = fa[top[x]] ;
}
if(dep[x] > dep[y]) swap(x,y) ;
ans += query(1,1,n,l[x],l[y]) ;
return ans ;
}
int qrange_max(int u,int v) {
int ans = -99999 ;
while(top[u] != top[v]) {
if(dep[top[u]] < dep[top[v]]) swap(u,v) ;
ans = max(ans,qmax(1,1,n,l[top[u]],l[u])) ;
u = fa[top[u]] ;
}
if(dep[u] < dep[v]) swap(u,v);
ans=max(ans,qmax(1,1,n,l[v],l[u]));
return ans ;
}
void updrange(int x,int y,int k) {
while(top[x] != top[y]) {
if(dep[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x,y) ;
update(1,1,n,l[top[x]],l[x],k) ;
x = fa[top[x]] ;
}
}
if(dep[x] > dep[y]) swap(x,y) ;
update(1,1,n,l[x],l[y],k) ;
return ;
}
void dfs1(int x,int f , int deep) {
dep[x] = deep ;
fa[x] = f ;
size[x] = 1 ;
for(int i = head[x] ; i ;i = a[i].next) {
int v = a[i].y ;
if(v != fa[x]) {
dep[v] = dep[x] + 1 ;
fa[v] = x ;
dfs1(v,x,deep+1) ;
size[x] += size[v] ;
if(size[v] >size[son[x]]) son[x] = v ;
}
}
}
void dfs2(int x ,int topf) {
l[x] = ++cnt ;
wt[cnt] = w[x] ;
top[x] = topf ;
if(!son[x]) return ;
dfs2(son[x],topf) ;
for(int i = head[x] ; i ; i = a[i].next) {
int v = a[i].y ;
if(v != fa[x] && v != son[x]) dfs2(v,v) ;
}
}
void change(int u ,int l ,int r ,int ll ,int rr ,int w) {
if(l == ll && r == rr) {
tree[u].maxn = tree[u].sum = w ;
return ;
}
int mid = (l+r) >> 1 ;
pushdown(u,l,r) ;
if(rr <= mid) change(tree[u].lc,l,mid,ll,rr,w) ;
else if(ll >mid) change(tree[u].rc,mid+1,r,ll,rr,w) ;
else {
change(tree[u].lc,l,mid,ll,mid,w) ;
change(tree[u].rc,mid+1,r,mid+1,rr,w) ;
}
pushup(u) ;
}
int main (){
cin >> n ;
for(int i = 1 ; i <= n-1 ; i ++) {
int x , y ;
cin >> x >> y ;
add(x,y) ;
add(y,x) ;
}
for(int i = 1 ; i <= n ; i ++) {
cin >> w[i] ;
}
cin >> m ;
dfs1(1,0,1) ;
dfs2(1,1) ;
build(1,1,n) ;
while(m --) {
string opt ;
int k , x , y , z ;
cin >> opt ;
if(opt == "CHANGE") {
cin >> x >> y ;
change(1,1,n,l[x],l[x],y) ;
}else if(opt == "QMAX") {
cin >> x >> y ;
cout << qrange_max(x,y) << endl ;
}else if(opt == "QSUM") {
cin >> x >> y ;
cout << qrange(x,y) <<endl ;
}
}
return 0 ;
}