u->v最优解=极大卖出-极小买入,记最近公共祖先r,穷举三种情况:
u->v最优解=u->r最优解
u->v最优解=r->v最优解
u->v最优解=r->v极大卖出-u->r极小买入
</pre><pre name="code" class="cpp">#include<iostream>
#include <string>
#include<vector>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;
#define lch(i) ((i)<<1)
#define rch(i) ((i)<<1|1)
#define sqr(i) ((i)*(i))
#define pii pair<int,int>
#define mp make_pair
#define FOR(i,b,e) for(int i=b;i<=e;i++)
#define ms(a) memset(a,0,sizeof(a))
const int maxnum = 50005;
struct node
{
int v,next;
}edge[maxnum*2];
struct node1
{
int v,nth,next,dir;
}qedge[maxnum*2];
int p[maxnum],max1[maxnum],min1[maxnum],r2rt[maxnum],rt2r[maxnum],pre[maxnum];
int head[maxnum],query[maxnum],vis[maxnum];
int ans[maxnum];
int ca[maxnum];
int find1(int i){
if(p[i]==i){
return p[i];
}
int tmp = p[i];
p[i]=find1(p[i]);
r2rt[i]=max(max(r2rt[i],r2rt[tmp]),max1[i]-min1[tmp]);
rt2r[i]=max(max(rt2r[i],rt2r[tmp]),max1[tmp]-min1[i]);
max1[i]=max(max1[tmp],max1[i]);
min1[i]=min(min1[tmp],min1[i]);
return p[i];
}
void uniontree(int rx,int ry){
p[ry]=rx;
}
void dfs(int rt){
p[rt]=rt;
for(int i=head[rt];i!=-1;i=edge[i].next){
if(edge[i].v==pre[rt])continue;
pre[edge[i].v]=rt;
dfs(edge[i].v);
uniontree(rt,find1(edge[i].v));
}
vis[rt]=1;
for(int i=query[rt];i!=-1;i=qedge[i].next){
if(!vis[qedge[i].v])continue;
int ca = find1(qedge[i].v);
if(qedge[i].dir==0){
int rtr=0,mi=min1[rt],pi=rt;
while(pi!=ca){
rtr=max(max(rtr,max1[pre[pi]]-max1[pi]),max1[pre[pi]]-mi);
mi = min(mi,min1[pre[pi]]);
pi=pre[pi];
}
ans[qedge[i].nth]=max(max(rtr,r2rt[qedge[i].v]),max1[qedge[i].v]-mi);
}
else{
int rrt=0,ma=max1[rt],pi=rt;
while(pi!=ca){
rrt=max(max(rrt,max1[pi]-max1[pre[pi]]),ma-min1[pre[pi]]);
ma = max(ma,max1[pre[pi]]);
pi=pre[pi];
}
ans[qedge[i].nth]=max(max(rrt,rt2r[qedge[i].v]),ma-min1[qedge[i].v]);
}
}
}
int e=0;
void add(int u,int v){
edge[e].v=v;
edge[e].next=head[u];
head[u]=e++;
}
int f=0;
void addq(int u,int v,int i,int dir){
qedge[f].v=v;
qedge[f].next=query[u];
qedge[f].nth=i;
qedge[f].dir=dir;
query[u]=f++;
}
int main()
{
int n,q,u,v;
scanf("%d",&n);
FOR(i,1,n){
scanf("%d",&max1[i]);
min1[i]=max1[i];
r2rt[i]=rt2r[i]=0;
head[i]=-1;
query[i]=-1;
vis[i]=0;
}
FOR(i,1,n-1){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
scanf("%d",&q);
FOR(i,1,q){
scanf("%d%d",&u,&v);
addq(u,v,i,0);
addq(v,u,i,1);
}
ms(p);
pre[1]=0;
dfs(1);
FOR(i,1,q){
printf("%d\n",ans[i]);
}
return 0;
}