很容易想到要用动态树来维护。
不过这一道题我被恶心了一下,主要是翻转操作会影响结果,所以应该同时维护从左到右和从右到左的结果。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
template<typename T>inline void qr(T &x){
x=0;int f=0;char s=getchar();
while(s<'0'||'9'<s)f|=s=='-',s=getchar();
while('0'<=s&&s<='9')x=x*10+s-48,s=getchar();
x=f?-x:x;
}
#define lc ch[x][0]
#define rc ch[x][1]
#define ls(x) ch[x][0]
#define rs(x) ch[x][1]
const int mxn=5e4+10;
int d[mxn],fa[mxn],ch[mxn][2],lmax[mxn],rmax[mxn],dmx[mxn],dmn[mxn];
bool rv[mxn];int lazy[mxn],sta[mxn];
bool nrt(int x){return ls(fa[x])==x||rs(fa[x])==x;}
void crv(int x){
if(!x)return;
swap(lc,rc);rv[x]^=1;
swap(lmax[x],rmax[x]);
}
void add(int x,int val){
if(!x)return;
d[x]+=val,dmx[x]+=val,dmn[x]+=val;
lazy[x]+=val;
}
void pushdown(int x){
if(rv[x])
crv(lc),crv(rc),rv[x]=0;
if(lazy[x])
add(lc,lazy[x]),add(rc,lazy[x]),lazy[x]=0;
}
void update(int x){
lmax[x]=max(max(lmax[lc],lmax[rc]),max(d[x],dmx[rc])-min(d[x],dmn[lc]));
rmax[x]=max(max(rmax[lc],rmax[rc]),max(d[x],dmx[lc])-min(d[x],dmn[rc]));
dmx[x]=max(max(dmx[lc],dmx[rc]),d[x]);
dmn[x]=min(min(dmn[lc],dmn[rc]),d[x]);
}
void rotate(int x){
int y=fa[x],z=fa[y],w=rs(y)==x;
if(nrt(y))ch[z][rs(z)==y]=x;fa[x]=z;
fa[ch[y][w]=ch[x][1-w]]=y;
ch[x][1-w]=y;fa[y]=x;
update(y);
}
void splay(int p){
int x=p,tp=0;
sta[++tp]=x;
while(nrt(x))sta[++tp]=x=fa[x];
while(tp)pushdown(sta[tp--]);x=p;
while(nrt(x)){
int y=fa[x],z=fa[y];
if(nrt(y))
(rs(z)==y)^(rs(y)==x)?rotate(x):rotate(y);
rotate(x);
}
update(x);
}
void access(int x){
for(int y=0;x;x=fa[y=x])
splay(x),rc=y,update(x);
}
void makeroot(int x){
access(x);
splay(x);
crv(x);
}
void link(int x,int y){
makeroot(x);
fa[x]=y;
}
void split(int x,int y){
makeroot(x);
access(y);
splay(y);
}
int main(){
// freopen("2.in","r",stdin);
// freopen("2.out","w",stdout);
int n;qr(n);
for(int i=1;i<=n;i++){
qr(d[i]);
dmx[i]=dmn[i]=d[i];
}
dmn[0]=1e9+10;
for(int i=1;i<n;i++){
int x,y;qr(x),qr(y);
link(x,y);
}
int q;qr(q);
while(q--){
int x,y,v;qr(x),qr(y),qr(v);
split(x,y);
printf("%d\n",lmax[y]);
add(y,v);
}
return 0;
}