比赛 2025.10.24 评测结果 AAAAAAAAATTTTTTTTTTT
题目名称 坡伊踹 最终得分 45
用户昵称 梦那边的美好ME 运行时间 45.355 s
代码语言 C++ 内存使用 23.10 MiB
提交时间 2025-10-24 10:28:29
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define ll long long

int n,q;
int a[210000];
vector<pair<int,int>> g[210000];

int depth[210000];
ll dist[210000];
int fa[18][210000];

void dfs(int u,int p,int d,ll dis){
    fa[0][u]=p;
    depth[u]=d;
    dist[u]=dis;
    for (auto &e:g[u]){
        int v=e.first,w=e.second;
        if (v==p) continue;
        dfs(v,u,d + 1,dis + w);
    }
}

void solve(){
    dfs(1,0,0,0);
    for (int k=1;k<18;k++){
        for (int i=1;i<=n;i++){
            fa[k][i]=fa[k-1][fa[k-1][i]];
        }
    }
}

int lca(int u,int v){
    if (depth[u]<depth[v]) swap(u,v);
    int diff=depth[u]-depth[v];
    for (int k=17;k>=0;k--){
        if (diff >> k & 1){
            u=fa[k][u];
        }
    }
    if (u==v) return u;
    for (int k=17;k>=0;k--){
        if (fa[k][u] != fa[k][v]){
            u=fa[k][u];
            v=fa[k][v];
        }
    }
    return fa[0][u];
}

ll get_dist(int u,int v){
    int l=lca(u,v);
    return dist[u]+dist[v]-2*dist[l];
}

bool check(int u,int v,int ans){
    int l=lca(u,v);
    int x=u;
    while (1){
        if (a[x]<=ans && get_dist(x,u)<=ans) return 1;
        if (x==l) break;
        x=fa[0][x];
    }
    x=v;
    while (x!=l){
        if (a[x]<=ans&&get_dist(x,u)<=ans) return 1;
        x=fa[0][x];
    }
    return 0;
}

int main(){
	freopen("poitry.in","r",stdin);
	freopen("poitry.out","w",stdout);
    scanf("%d %d",&n,&q);
    for (int i=1;i<=n;i++){
    	scanf("%d",&a[i]);
    }
    for (int i=0;i<n-1;i++){
        int u,v,w;
        scanf("%d %d %d",&u,&v,&w);
        g[u].push_back({v,w});
        g[v].push_back({u,w});
    }
    solve();
    while (q--){
        int u,v;
        scanf("%d %d",&u,&v);
        if (u==v){
        	printf("%d\n",max(a[u],0));
            continue;
        }
        int l=0,r=1e9;
        while (l<r){
            int mid=(l+r)/2;
            if (check(u,v,mid)){
                r=mid;
            }else l=mid + 1;
        }
        printf("%d\n",l);
    }
    return 0;
}