比赛 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;
}