比赛 2025.10.24 评测结果 AAAAAAAAAAAATTAATTTT
题目名称 坡伊踹 最终得分 70
用户昵称 徐诗畅 运行时间 39.867 s
代码语言 C++ 内存使用 36.78 MiB
提交时间 2025-10-24 11:26:30
显示代码纯文本
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int n,q,t[N<<2],a[N],b[N];
int head[N],cnt;
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return x*f;
}
struct edge{int v,w,nex;}e[N<<1];
void addedge(int u,int v,int w){
	e[++cnt].v=v;
	e[cnt].w=w;
	e[cnt].nex=head[u];
	head[u]=cnt;
}
void push_up(int p){t[p]=min(t[p<<1],t[p<<1|1]);}
void build(int p,int l,int r){
	if(l==r){t[p]=b[l]; return;}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	push_up(p);
}
int query(int p,int l,int r,int L,int R){
	if(L<=l&&R>=r) return t[p];
	int mid=(l+r)>>1;
	int res=2e14;
	if(L<=mid) res=min(res,query(p<<1,l,mid,L,R));
	if(R>mid) res=min(res,query(p<<1|1,mid+1,r,L,R));
	return res;
}
int dfn[N],siz[N],son[N],deep[N],dis[N],fa[N][21],num,top[N];
void dfs1(int u,int f){
	fa[u][0]=f; siz[u]=1; deep[u]=deep[f]+1;
	for(int i=1;(1<<i)<=deep[u];i++)
		fa[u][i]=fa[fa[u][i-1]][i-1];
	for(int i=head[u];i;i=e[i].nex){
		int v=e[i].v; if(v==f) continue;
		dis[v]=dis[u]+e[i].w;
		dfs1(v,u); siz[u]+=siz[v];
		if(siz[v]>siz[son[u]]) son[u]=v;
	}
}
void dfs2(int u,int tp){
	top[u]=tp; dfn[u]=++num; b[num]=a[u];
	if(!son[u]) return;
	dfs2(son[u],tp);
	for(int i=head[u];i;i=e[i].nex){
		int v=e[i].v; if(v==fa[u][0]||v==son[u]) continue;
		dfs2(v,v);
	}
}
int ask(int u,int v){
	int res=2e14;
	while(top[u]!=top[v]){
		if(deep[top[u]]<deep[top[v]]) swap(u,v);
		res=min(res,query(1,1,n,dfn[top[u]],dfn[u]));
		u=fa[top[u]][0];
	}
	if(deep[u]<deep[v]) swap(u,v);
	res=min(res,query(1,1,n,dfn[v],dfn[u]));
	return res;
}
int LCA(int u,int v){
	while(top[u]!=top[v]){
		if(deep[top[u]]<deep[top[v]]) swap(u,v);
		u=fa[top[u]][0];
	}
	if(deep[u]<deep[v]) return u;
	return v;
}
int jump(int u, int d){
	int cur=u;
	for(int i=18;i>=0;i--){ //cout<<cur<<" "<<i<<" "<<fa[cur][i]<<endl;
		if(fa[cur][i]&&dis[u]-dis[fa[cur][i]]<=d){
			cur=fa[cur][i];
		}
	}
	return cur;
}
/*int jump1(int u, int d){
	int cur=u;
	for(int i=18;i>=0;i--){
		if(fa[cur][i]&&dis[u]-dis[cur]<d&&dis[u]-dis[fa[cur][i]]>d){
			cur=fa[cur][i];
		}
	}
	return cur;
}*/
int solve(int u,int v){
	int lca=LCA(u,v);
	int L=dis[u]+dis[v]-2*dis[lca];
	int d1=dis[u]-dis[lca];
	int l=0,r=2e14;
	int ans=r;
	while(l<=r){
		int mid=(l+r)>>1;
		int x0;
	    if(mid>=L){x0=v;}
	    else{
   			if(mid<=d1) x0=jump(u,mid);
   			else{
        		int re=mid-d1;
        		int th=dis[lca]+re;
        		int cur=v;
       			for(int i=18;i>=0;i--){
         			if(fa[cur][i]&&dis[fa[cur][i]]>th) cur=fa[cur][i];
      		  	}
      	  		if(dis[cur]>th) cur=fa[cur][0];
	   		    x0=cur;
  			}
		}
		int mina=ask(u,x0);
	//	cout<<u<<" "<<x0<<" "<<ask(u,x0)<<" "<<mid<<endl;
		if(mina<=mid){
			ans=mid;
			r=mid-1;
		}
		else l=mid+1;
	}
	return ans;
}
void write(int x)
{
    if(x<0)
        putchar('-'),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
    return;
}

signed main(){
	freopen("poitry.in","r",stdin);
	freopen("poitry.out","w",stdout);
	n=read(); q=read();
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<n;i++){
		int u,v,w; u=read(); v=read(); w=read();
		addedge(u,v,w); addedge(v,u,w);
	}
	dfs1(1,0); dfs2(1,1); 
	build(1,1,n); //cout<<jump1(5,4); 
	while(q--){
		int u,v; scanf("%lld%lld",&u,&v);
		write(solve(u,v)); cout<<"\n";
	}
	return 0;
}