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