24pts
查看原帖
24pts
427590
SHENTONG_ZY楼主2024/11/27 14:24

record

dp1[i]为i到儿子(包括自己)演讲获得的最大价值

dp2[i]为i到祖先或祖先儿子演讲获得的最大价值

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+100;
int n,q,u,v,w,idx,head[N],x,y;
long long c[N];
struct Edge{
	int v,w,next;
}e[2*N];
void add(int u,int v,int w){
	e[++idx].v=v;
	e[idx].w=w;
	e[idx].next=head[u];
	head[u]=idx;
}
int fat[N],dep[N],siz[N],mason[N],masonw[N];
long long dp1[N],dp2[N];
void dfs1(int now,int fa){
	fat[now]=fa;
	dep[now]=dep[fa]+1;
	siz[now]=1;
	int mas=-1;
	for(int i=head[now];i;i=e[i].next){
		int to=e[i].v;
		if(to==fa) continue;
		dfs1(to,now);
		siz[now]+=siz[to];
		if(siz[to]>mas){
			mas=siz[to];
			mason[now]=to;
			masonw[now]=e[i].w;
		}
		dp1[now]=max(dp1[now],dp1[to]-2*e[i].w);
	}
	dp1[now]=max(dp1[now],c[now]);
}
int top[N],dfn[N],cost[N],cnt;
long long value[N];
void dfs2(int now,int fa,int topp,int w){
	top[now]=topp;
	dfn[now]=++cnt;
	cost[cnt]=w;
	value[cnt]=dp1[now];
	if(siz[now]>1) dfs2(mason[now],now,topp,masonw[now]);
	for(int i=head[now];i;i=e[i].next){
		int to=e[i].v;
		if(to==fa||to==mason[now]) continue;
		dfs2(to,now,to,e[i].w);
	}
	dp2[now]=max(dp2[fa],dp1[fa])-w*2;
}
struct segement_Tree{
	long long sum;
	long long ma;
}t[4*N];
void build(int now,int l,int r){
	if(l==r){
		t[now].ma=value[l];
		t[now].sum=cost[l];
		return;
	}
	int mid=(l+r)/2;
	build(now*2,l,mid);
	build(now*2+1,mid+1,r);
	t[now].ma=max(t[now*2].ma,t[now*2+1].ma);
	t[now].sum=t[now*2].sum+t[now*2+1].sum;
}
long long qs(int now,int l,int r,int ml,int mr){
	if(ml<=l&&r<=mr){
		return t[now].sum;
	}
	int mid=(l+r)/2;
	long long res=0;
	if(ml<=mid) res+=qs(now*2,l,mid,ml,mr);
	if(mr>=mid+1) res+=qs(now*2+1,mid+1,r,ml,mr);
	return res;
}
long long qm(int now,int l,int r,int ml,int mr){
	if(ml<=l&&r<=mr){
		return t[now].ma;
	}
	int mid=(l+r)/2;
	long long res1=-0x7fffffff,res2=-0x7fffffff;
	if(ml<=mid) res1=qm(now*2,l,mid,ml,mr);
	if(mr>=mid+1) res2=qm(now*2+1,mid+1,r,ml,mr);
	return max(res1,res2);
}
long long query(int x,int y){
	int X=x,Y=y;
	long long ans=0;
	long long maa=-0x7fffffff;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ans+=qs(1,1,n,dfn[top[x]],dfn[x]);
		maa=max(maa,qm(1,1,n,dfn[top[x]],dfn[x]));
		x=fat[top[x]];
	}
	if(dep[x]<dep[y]) swap(x,y);
	ans+=qs(1,1,n,dfn[y],dfn[x]);
	ans-=cost[dfn[y]];
	maa=max(maa,qm(1,1,n,dfn[y],dfn[x]));//cout<<maa<<" ";
	maa=max(maa,dp2[y]);//y为LCA
	//cout<<ans<<" "<<maa<<"\n";
	return c[X]+c[Y]-ans+maa;
}
int main(){
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		scanf("%d",&c[i]);
	}
	for(int i=1;i<n;i++){
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
		add(v,u,w);
	}
	for(int i=0;i<=n+1;i++){
		dp1[i]=-0x7fffffff;
		dp2[i]=-0x7fffffff;
	}
	dfs1(1,0);
	dfs2(1,0,1,0);
	build(1,1,n);
	while(q--){
		scanf("%d%d",&x,&y);
		printf("%lld\n",query(x,y));
	}

	return 0;
}
2024/11/27 14:24
加载中...