rt,Hack 在代码末尾。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
// #define debug1(x) cerr<<#x<<"="<<x<<" "
// #define debug2(x) cerr<<#x<<"="<<x<<"\n"
const int inf=1e16,maxn=5e4+10;
int n,a[maxn],q;
vector<int>v[maxn];
//树剖第一次 DFS
int wc[maxn],size[maxn],dep[maxn],fa[maxn];
bool isw[maxn];
void dfs1(int x,int father){
size[x]=1;
fa[x]=father;
int maxs=0,id=0;
for(int y:v[x]){
if(y!=fa[x]){
dep[y]=dep[x]+1;
dfs1(y,x);
size[x]+=size[y];
if(size[y]>maxs)maxs=size[y],id=y;
}
}
wc[x]=id;
isw[id]=1;
}
//树剖第二次 DFS
int p[maxn],d[maxn],top[maxn],tot;
void dfs2(int x){
d[++tot]=x;
p[x]=tot;
top[x]=isw[x]?top[fa[x]]:x;
if(wc[x])dfs2(wc[x]);
for(int y:v[x]){
if(y!=fa[x] and y!=wc[x])dfs2(y);
}
}
struct node{int max,min,ans1,ans2,tag;}w[4*maxn];
node operator + (node a,node b){
if(!a.min)a.min=inf;
if(!b.min)b.min=inf;
return node{max(a.max,b.max),min(a.min,b.min),max({a.ans1,b.ans1,a.max-b.min}),max({a.ans2,b.ans2,b.max-a.min}),0};
}
void pushup(int id){w[id]=w[id*2]+w[id*2+1];}
void build(int id,int l,int r){
if(l==r){w[id]=node{a[d[l]],a[d[l]],0,0,0};return;}
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
pushup(id);
}
void maketag(int id,int pos){
w[id].tag+=pos;
w[id].max+=pos;
w[id].min+=pos;
}
void pushdown(int id){
if(w[id].tag){
maketag(id*2,w[id].tag);
maketag(id*2+1,w[id].tag);
w[id].tag=0;
}
}
bool inr(int l,int r,int cl,int cr){return l<=r and cl<=l and r<=cr;}
node check(int id,int l,int r,int cl,int cr){
// debug2(id);
if(inr(l,r,cl,cr))return w[id];
pushdown(id);
int mid=(l+r)/2;
node ans={0,0,0,0,0};
if(cl<=mid)ans=ans+check(id*2,l,mid,cl,cr);
if(cr>mid)ans=ans+check(id*2+1,mid+1,r,cl,cr);
return ans;
}
void update(int id,int l,int r,int cl,int cr,int pos){
if(inr(l,r,cl,cr)){maketag(id,pos);return;}
pushdown(id);
int mid=(l+r)/2;
if(cl<=mid)update(id*2,l,mid,cl,cr,pos);
if(cr>mid)update(id*2+1,mid+1,r,cl,cr,pos);
pushup(id);
}
vector<node>res1,res2;
int check(int x,int y,int val){
res1.clear();res2.clear();
while(top[x]!=top[y]){
if(dep[top[y]]>dep[top[x]]){//ans1 维护,左大右小
res1.push_back(check(1,1,n,p[top[y]],p[y]));
// debug2(p[top[y]]);debug2(p[y]);
update(1,1,n,p[top[y]],p[y],val);
y=fa[top[y]];
}
else{//ans2 维护,右大左小
res2.push_back(check(1,1,n,p[top[x]],p[x]));
// debug2(p[top[x]]);debug2(p[x]);
update(1,1,n,p[top[x]],p[x],val);
x=fa[top[x]];
}
}
if(dep[y]>dep[x])res1.push_back(check(1,1,n,p[x],p[y])),update(1,1,n,p[x],p[y],val)/*,debug2(p[x]),debug2(p[y])*/;
else res2.push_back(check(1,1,n,p[y],p[x])),update(1,1,n,p[y],p[x],val)/*,debug2(p[y]),debug2(p[x])*/;
node l={0,inf,0,0,0},r={0,inf,0,0,0};
for(node p:res2){l=l+p;}
for(node p:res1){r=r+p;}
// debug2(l.ans1);debug2(r.ans2);debug2(r.max);debug2(l.min);
return max({l.ans1,r.ans2,r.max-l.min});
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1,p,q;i<n;i++){
cin>>p>>q;
v[p].push_back(q);
v[q].push_back(p);
}
dfs1(1,0);
dfs2(1);
build(1,1,n);
cin>>q;
while(q--){
int posa,posb,posv;cin>>posa>>posb>>posv;
cout<<check(posa,posb,posv)<<"\n";
}
/*debug2(check(1,1,n,1,2).ans2);
debug2(check(1,1,n,1,2).max);
debug2(check(1,1,n,1,2).min);*/
return 0;
}
//Hack
/*
6
2 8 6 5 11 53
1 2
1 3
1 4
3 5
3 6
1
1 6 10
51
*/