社区讨论
树剖T 56,求条
P11324【MX-S7-T2】「SMOI-R2」Speaker参与者 3已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mhz4fkda
- 此快照首次捕获于
- 2025/11/15 01:17 4 个月前
- 此快照最后确认于
- 2025/11/16 13:56 4 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 200100
int n,q,c[N],dis[N],fa[N],son[N],top[N],siz[N],dep[N],lca;
int u,v,w,x,y,ans,mx[N],dfn[N],idx;
struct edge{int nex,val;};
vector<edge>p[N];
struct Segment_tree{int l,r,mx;}tr[N<<2];
void pushup(int now){tr[now].mx=max(tr[now*2].mx,tr[now*2+1].mx);}
void build(int now,int l,int r){
tr[now].l=l,tr[now].r=r;
if(l==r){tr[now].mx=mx[l];return;}
int mid=(l+r)>>1;
build(now*2,l,mid),build(now*2+1,mid+1,r);
pushup(now);
}
int query(int now,int l,int r){
if(tr[now].r<l||r<tr[now].l)return 0;
if(l<=tr[now].l&&tr[now].r<=r)return tr[now].mx;
return max(query(now*2,l,r),query(now*2+1,l,r));
}
void dfs1(int x,int fat){
fa[x]=fat,dep[x]=dep[fat]+1;
for(auto y:p[x]){
if(y.nex==fat)continue;
dis[y.nex]=y.val+dis[x],dfs1(y.nex,x);
siz[x]+=siz[y.nex];
if(siz[y.nex]>siz[son[x]])son[x]=y.nex;
}
}
void dfs2(int x,int fat){
dfn[x]=++idx;
if(son[fat]==x)top[x]=top[fat];
else top[x]=x;
if(son[x])dfs2(son[x],x);
for(auto y:p[x]){
if(y.nex!=fat&&y.nex!=son[x]){
dfs2(y.nex,x);
}
}
}
void dfs3(int x,int father){
mx[dfn[x]]=c[x];
for(auto y:p[x]){
if(y.nex!=father){
dfs3(y.nex,x);
mx[dfn[x]]=max(mx[dfn[x]],mx[dfn[y.nex]]-2*y.val);
}
}
}
void dfs4(int x,int father){
for(auto y:p[x]){
if(y.nex!=father){
mx[dfn[y.nex]]=max(mx[dfn[y.nex]],mx[dfn[x]]-2*y.val);
dfs4(y.nex,x);
}
}
}
int tree_query(int x,int y){
int ans=-2e9;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans=max(ans,query(1,dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
if(dep[x]<dep[y])lca=x;
else lca=y;
ans=max(ans,query(1,min(dfn[x],dfn[y]),max(dfn[x],dfn[y])));
return ans;
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++)cin>>c[i];
for(int i=1;i<n;i++){
cin>>u>>v>>w;
p[u].push_back({v,w}),p[v].push_back({u,w});
}
dfs1(1,0),dfs2(1,0),dfs3(1,0),dfs4(1,0);
build(1,1,n);
while(q--){
cin>>x>>y;
int t=tree_query(x,y);
cout<<c[x]+c[y]-(dis[x]+dis[y]-2*dis[lca])+t<<'\n';
}
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...