| 比赛 | 2025.10.24 | 评测结果 | AAAAAAAAAAAAAAAAAAAA | 
    | 题目名称 | 坡伊踹 | 最终得分 | 100 | 
    | 用户昵称 | 梦那边的美好TE | 运行时间 | 21.050 s | 
    | 代码语言 | C++ | 内存使用 | 48.21 MiB | 
    | 提交时间 | 2025-10-24 11:28:04 | 
显示代码纯文本
#include <iostream>
#include <cstdio>
#define int long long  
using namespace std;
const int N=5e5+10;
int n,q,a[N],to[N],nxt[N<<1],val[N<<1],ver[N],idx;
int f[N][21],g[N][21],d[N],de[N];
void add(int x,int y,int z){
	to[++idx]=y,nxt[idx]=ver[x],ver[x]=idx,val[idx]=z;
}
void dfs(int x,int fa){
	for(int i=1;i<=20;i++){
		f[x][i]=f[f[x][i-1]][i-1];
		g[x][i]=min(g[x][i-1],g[f[x][i-1]][i-1]); 
	}
	for(int i=ver[x];i;i=nxt[i]){
		int y=to[i];
		if(y==fa)continue;
		d[y]=d[x]+val[i],de[y]=de[x]+1;
		f[y][0]=x,g[y][0]=a[x];
		dfs(y,x);
	}
	return;
}
int LCA(int a,int b){
	if(de[a]<de[b])swap(a,b);
	for(int i=20;i>=0;i--)if(de[f[a][i]]>=de[b])a=f[a][i];
	if(a==b)return a;
	for(int i=20;i>=0;i--)if(f[a][i]!=f[b][i])a=f[a][i],b=f[b][i];
	return f[a][0];
}
bool check(int u,int v,int w,int k){
	int x=u,y=u,ans=a[u],kk;
	if(d[u]-d[w]>k){
		for(int i=20;i>=0;i--)if(d[u]-d[f[x][i]]<=k)x=f[x][i];
		for(int i=20;i>=0;i--)if(d[f[y][i]]>=d[x]){
			ans=min(ans,g[y][i]),y=f[y][i];
		}
	}else{
		kk=k-(d[u]-d[w]);x=v;
		for(int i=20;i>=0;i--)if(d[f[x][i]]-d[w]>kk)x=f[x][i];
		if(d[x]-d[w]>kk)x=f[x][0];
		ans=min(ans,a[x]);
		for(int i=20;i>=0;i--)if(d[f[y][i]]>=d[w]){
			ans=min(ans,g[y][i]),y=f[y][i];
		}
		for(int i=20;i>=0;i--)if(d[f[x][i]]>=d[w]){
			ans=min(ans,g[x][i]),x=f[x][i];
		}
	}
	return ans<=k;
}
signed main(){
	freopen("poitry.in","r",stdin);
	freopen("poitry.out","w",stdout);
	scanf("%lld %lld",&n,&q);d[1]=1,de[1]=1;
	for(int i=1;i<=n;i++)scanf("%lld",a+i);
	for(int i=1,u,v,w;i<n;i++){
		scanf("%lld %lld %lld",&u,&v,&w);
		add(u,v,w),add(v,u,w);
	}
	dfs(1,0);
	int u,v,w,L,R,mid;
	while(q--){
		scanf("%lld %lld",&u,&v);
		L=0,R=1e9,w=LCA(u,v);
		while(L<R){
			mid=(L+R)>>1;
			if(check(u,v,w,mid))R=mid;
			else L=mid+1;
		}
		printf("%lld\n",R);	
	}
	return 0;
}