传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1036
卧槽要注意权值可能为负,所以qmax的时候ans要设成INT_MIn啊啊啊啊
Code:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<climits>
#include<vector>
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define L i<<1
#define R i<<1|1
using namespace std;
int n,m;
const int maxn=30001;
vector<int>G[maxn];
int dep[maxn],son[maxn],siz[maxn],fa[maxn],top[maxn],w[maxn],z=0,a[maxn];
void add(int u,int v){
G[u].push_back(v);
G[v].push_back(u);
}
void dfs(int u){
son[u]=0;siz[u]=1;
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(v!=fa[u]){
dep[v]=dep[u]+1;
fa[v]=u;
dfs(v);
if(siz[v]>siz[son[u]])son[u]=v;
siz[u]+=siz[v];
}
}
}
void build(int u,int tp){
w[u]=++z;top[u]=tp;
if(son[u])build(son[u],tp);
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(v!=fa[u]&&v!=son[u])
build(v,v);
}
}
struct node{
int sum,Max;
};
struct seg_tree{
node t[maxn<<2];
void maintain(int i){
t[i].sum=t[L].sum+t[R].sum;
t[i].Max=max(t[L].Max,t[R].Max);
}
/*void build(int i,int l,int r){
if(l>r)return;
if(l==r){
t[i].sum=t[i].Max=a[l];
return;
}
int mid=l+r>>1;
build(lson);build(rson);
maintain(i);
}*/
void change(int i,int l,int r,int p,int x){
if(l>r)return;
if(l==r){
t[i].sum=t[i].Max=x;
return;
}
int mid=l+r>>1;
if(p<=mid)change(lson,p,x);
if(p>mid) change(rson,p,x);
maintain(i);
}
int qmax(int i,int l,int r,int l0,int r0){
if(l>r)return 0;
if(l0<=l&&r0>=r)
return t[i].Max;
int ans=INT_MIN;
int mid=l+r>>1;
if(l0<=mid)ans=max(ans,qmax(lson,l0,r0));
if(r0>mid) ans=max(ans,qmax(rson,l0,r0));
return ans;
}
int qsum(int i,int l,int r,int l0,int r0){
if(l>r)return 0;
if(l0<=l&&r0>=r)
return t[i].sum;
int ans=0;
int mid=l+r>>1;
if(l0<=mid)ans+=qsum(lson,l0,r0);
if(r0>mid) ans+=qsum(rson,l0,r0);
return ans;
}
}T;
void change(int u,int x){
T.change(1,1,n,w[u],x);
}
void deb(){
for(int i=1;i<=14;i++)
printf("#%d sum:%d Max:%d\n",i,T.t[i].sum,T.t[i].Max);
}
int Qmax(int u,int v){
int ans=INT_MIN;
while(top[u]!=top[v]){
if(dep[top[u]]>dep[top[v]]){
int a=w[u],b=w[top[u]];
if(a>b)swap(a,b);
ans=max(ans,T.qmax(1,1,n,a,b));
u=fa[top[u]];
}else{
int a=w[v],b=w[top[v]];
if(a>b)swap(a,b);
ans=max(ans,T.qmax(1,1,n,a,b));
v=fa[top[v]];
}
}
int a=w[u],b=w[v];
if(a>b)swap(a,b);
ans=max(ans,T.qmax(1,1,n,a,b));
return ans;
}
int Qsum(int u,int v){
int ans=0;
while(top[u]!=top[v]){
if(dep[top[u]]>dep[top[v]]){
int a=w[u],b=w[top[u]];
if(a>b)swap(a,b);
ans+=T.qsum(1,1,n,a,b);
u=fa[top[u]];
}else{
int a=w[v],b=w[top[v]];
if(a>b)swap(a,b);
ans+=T.qsum(1,1,n,a,b);
v=fa[top[v]];
}
}
int a=w[u],b=w[v];
if(a>b)swap(a,b);
ans+=T.qsum(1,1,n,a,b);
return ans;
}
int main(){
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
}
dfs(1);build(1,1);//T.build(1,1,n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
T.change(1,1,n,w[i],a[i]);
}
scanf("%d",&m);
int u,v,x;
//deb();
while(m--){
char opt[5];
scanf("%s",opt);
if(opt[1]=='H'){//Change
scanf("%d%d",&u,&x);
change(u,x);
}else
if(opt[1]=='M'){//QMax
scanf("%d%d",&u,&v);
printf("%d\n",Qmax(u,v));
}else{
scanf("%d%d",&u,&v);
printf("%d\n",Qsum(u,v));
}
}
return 0;
}