参考别人的用在线的lca不知道为什么错。。
https://vjudge.net/solution/2554998
#include<algorithm>
#include<vector>
#include<cstring>
#include<string>
#include<iomanip>
#include<cstdio>
#include<stack>
#include<iostream>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
#define sf scanf
#define pf printf
#define mem(a,b) memset(a,b,sizeof(a));
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define mod 9901
#define N 100020
#define ULL unsigned long long
#define LL long long
#define inf 0x3f3f3f3f
#define mxn 25020
#define mxe 1002000
#define make_pair
//2017年08月16日08:14:03
int n,q;
int up[22][N],down[22][N],mx[22][N],mi[22][N],w[N],dep[N],fst[N],vv[N<<1],nxt[N<<1];
int tot,fa[22][N];
void init(){ mem(fst,-1);tot=0; }
void add(int u,int v){
vv[tot]=v;nxt[tot]=fst[u];fst[u]=tot++;
}
void dfs(int u,int p){
fa[0][u]=p;
if(p!=-1){
mx[0][u]=max(w[u],w[p]);
mi[0][u]=min(w[u],w[p]);
up[0][u]=max(0,w[u]-w[p]);
down[0][u]=max(0,w[p]-w[u]);
}
else{
up[0][u]=down[0][u]=-1;
mx[0][u]=-1;
mi[0][u]=inf;
}
for(int i=fst[u];~i;i=nxt[i]){
int v=vv[i];
if(v!=p){
dep[v]=dep[u]+1;
dfs(v,u);
}
}
}
void init_lca(){
dep[1]=1;
dfs(1,-1);
for(int k=0;k<=20;++k){
for(int i=1;i<=n;++i){
if(fa[k][i]==-1)fa[k+1][i]=-1;
else{
fa[k+1][i]=fa[k][fa[k][i]];
if(fa[k+1][i]!=-1){
mx[k+1][i]=max(mx[k][i],mx[k][fa[k][i]]);
mi[k+1][i]=min(mi[k][i],mi[k][fa[k][i]]);
//up[k+1][i]=max(max(up[k][i],up[k][fa[k][i]]),mx[k][fa[k][i]]-mi[k][i]);
//down[k+1][i]=max(max(down[k][i],down[k][fa[k][i]]),mx[k][i]-mi[k][fa[k][i]]);
}
}
}
}
}
int lca(int u,int v){
if(dep[u]>dep[v]){swap(u,v);}
for(int k=0;k<20;++k){
if((dep[v]-dep[u])>>k&1)
v=fa[k][v];
}
if(u==v)return u;
for(int k=19;k>=0;--k){
if(fa[k][u]!=fa[k][v])
u=fa[k][u],v=fa[k][v];
}
return fa[0][u];
}
int qmax1(int u,int p){
int ret=0,M=0;
if(u==p)return 0;
for(int k=19;k>=0;--k){
if(fa[k][u]!=-1&&dep[fa[k][u]]>=dep[p]){
ret=max(ret,up[k][u]);
ret=max(ret,M-mi[k][u]);
M=max(M,mx[k][u]);
u=fa[k][u];
}
}
pf("res: %d\n",ret);
return ret;
}
int qmax2(int u,int p){
if(u==p)return 0;
pf("%d %d\n",u,p);
int ret=0,M=inf;
for(int k=19;k>=0;--k){
if(fa[k][u]!=-1&&dep[fa[k][u]]>=dep[p]){
pf("k: %d\n",k);
pf("k:%d u:%d down[k][u]: %d\n",k,u,down[k][u]);
ret=max(ret,down[k][u]);
ret=max(ret,mx[k][u]-M);
M=min(M,mi[k][u]);
u=fa[k][u];
}
}
pf("res: %d\n",ret);
return ret;
}
int cas=0;
int solve(int u,int v){
int p=lca(u,v);
pf("CAs %d :%d\n",++cas,p);
if(p==u){return qmax2(v,u);}
else if(p==v){return qmax1(u,v);}
int ans=0;
ans=max(ans,qmax1(u,p));
ans=max(ans,qmax2(v,p));
pf("ans: %d\n",ans);
int MX=0,MI=inf;
for(int k=19;k>=0;--k){
if(fa[k][u]!=-1&&dep[fa[k][u]]>=dep[p]){
MX=max(MX,mx[k][u]);
u=fa[k][u];
}
if(fa[k][v]!=-1&&dep[fa[k][v]]>=dep[p]){
MI=min(MI,mi[k][v]);
v=fa[k][v];
}
}
ans=max(ans,MX-MI);
return ans;
}
int main(){
freopen("in.txt","r",stdin);
while(~sf("%d",&n)){
init();
rep(i,1,n){sf("%d",&w[i]);}
rep(i,1,n-1){int u,v;sf("%d%d",&u,&v);add(u,v),add(v,u);}
init_lca();
sf("%d",&q);
while(q--){
int u,v;sf("%d%d",&u,&v);
pf("%d\n",solve(u,v));
}
pf("test\n");
for(int i=1;i<=n;++i){
for(int k=0;k<=2;++k){
pf("%d ",down[k][i]);
}puts("");
}
}
}
这个地方还看到别人用并查集写,挺好的。。
参考http://blog.youkuaiyun.com/sdj222555/article/details/43003179