# 【笔记】P6419 [COCI2014-2015#1] Kamp 答辩做法

//If, one day, I finally manage to make my dreams a reality...
//I wonder, will you still be there by my side?
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
#define TIE cin.tie(0),cout.tie(0)
#define int long long
#define y1 cyy
#define fi first
#define se second
#define cnt1(x) __builtin_popcount(x)
#define mk make_pair
#define pb push_back
#define pii pair<int,int>
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define lbt(x) (x&(-x))
#define inf 0x3f3f3f3f
using namespace std;
int n,m,k[500005],dfn[500005],dis[500005],timer,u,v,w;
int dep[500005],fa[500005][20],F[500005],siz[500005];
bool fl[500005];
struct node{
int to,dis;
};
vector<node> a[500005];
bool cmp(int x,int y){
return dfn[x]<dfn[y];
}

void dfs0(int x,int f){
dfn[x]=++timer,dep[x]=dep[f]+1;
siz[x]=1;
fa[x][0]=f;
for(int i=1;i<=19;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
for(auto tmp:a[x]){
if(tmp.to==f) continue;
dis[tmp.to]=dis[x]+tmp.dis;
dfs0(tmp.to,x);
siz[x]+=siz[tmp.to];
}
}

int Lca(int u,int v){
if(dep[u]<dep[v]) swap(u,v);
for(int i=19;i>=0;--i){
if(dep[fa[u][i]]>=dep[v]) u=fa[u][i];
}
if(u==v) return u;
for(int i=19;i>=0;--i){
if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
}
return fa[u][0];
}
int Dis(int u,int v){
return dis[u]+dis[v]-dis[Lca(u,v)]*2;
}

set<pii> s;
int ans1;

void Insert(int x){
if(s.size()==2){
s.insert({dfn[x],x});
return ;
}
auto now=s.insert({dfn[x],x}).first;
auto Pre=prev(now),Nex=next(now);
if(Pre==s.begin()) Pre=--(s.find({inf,inf}));
if(Nex==(--s.end())) Nex=(++(s.begin()));
pii u=*Pre,v=*Nex;
ans1-=Dis(u.second,v.second);
ans1+=Dis(u.second,x)+Dis(x,v.second);
}
void Delete(int x){
if(s.size()==3){
s.erase(s.find({dfn[x],x}));
return ;
}
auto now=s.find({dfn[x],x});
auto Pre=prev(now),Nex=next(now);
if(Pre==s.begin()) Pre=--(s.find({inf,inf}));
if(Nex==(--s.end())) Nex=(++(s.begin()));
pii u=*Pre,v=*Nex;
ans1+=Dis(u.second,v.second);
ans1-=Dis(u.second,x)+Dis(x,v.second);
s.erase(now);
}

struct SGT{
struct node{
int l,r,mx,tag;
}tr[2000005];
void build(int i,int l,int r){
tr[i].l=l,tr[i].r=r,tr[i].tag=0;
if(l==r){
tr[i].mx=dis[k[l]];
return ;
}
int mid=(l+r)>>1;
build(ls(i),l,mid),build(rs(i),mid+1,r);
tr[i].mx=max(tr[ls(i)].mx,tr[rs(i)].mx);
}
void pushdown(int i){
if(tr[i].tag){
tr[ls(i)].tag+=tr[i].tag;
tr[rs(i)].tag+=tr[i].tag;
tr[ls(i)].mx+=tr[i].tag;
tr[rs(i)].mx+=tr[i].tag;
tr[i].tag=0;
}
}
void add(int i,int l,int r,int k){
if(tr[i].l>=l&&tr[i].r<=r){
tr[i].tag+=k,tr[i].mx+=k;
return ;
}
pushdown(i);
int mid=(tr[i].l+tr[i].r)>>1;
tr[i].mx=max(tr[ls(i)].mx,tr[rs(i)].mx);
}
int query(int i,int l,int r){
if(tr[i].l>=l&&tr[i].r<=r) return tr[i].mx;
pushdown(i);
int mid=(tr[i].l+tr[i].r)>>1,ans=0;
if(l<=mid) ans=max(ans,query(ls(i),l,r));
if(mid<r) ans=max(ans,query(rs(i),l,r));
return ans;
}
}sgt;

int getl(int x){
int l=1,r=m,ans=m;
while(l<=r){
int mid=(l+r)>>1;
if(dfn[k[mid]]>=x) ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}
int getr(int x){
int l=1,r=m,ans=1;
while(l<=r){
int mid=(l+r)>>1;
if(dfn[k[mid]]<=x) ans=mid,l=mid+1;
else r=mid-1;
}
return ans;
}

void dfs1(int x,int f,int dd){
int L=getl(dfn[x]),R=getr(dfn[x]+siz[x]-1);
if(x!=1){
if(!fl[x]) Insert(x);
//		cout<<x<<":"<<endl;
//		cout<<L<<' '<<R<<' '<<dd<<endl;
//		for(int i=1;i<=m;i++) cout<<sgt.query(1,i,i)<<' ';
//		cout<<endl;
F[x]=ans1;
F[x]-=sgt.query(1,1,m);
//		cout<<ans1<<' '<<sgt.query(1,1,m)<<endl;
if(!fl[x]) Delete(x);

}
for(auto tmp:a[x]){
if(tmp.to==f) continue;
dfs1(tmp.to,x,tmp.dis);
}
if(x!=1){
}
}

signed main(){
IOS;TIE;
cin>>n>>m;
for(int i=1;i<n;i++){
cin>>u>>v>>w;
a[u].pb({v,w}),a[v].pb({u,w});
}
dfs0(1,0);
for(int i=1;i<=m;i++) cin>>k[i];
sort(k+1,k+m+1,cmp);

sgt.build(1,1,m);
s.insert({-1,-1}),s.insert({inf,inf});
for(int i=1;i<=m;i++) Insert(k[i]),fl[k[i]]=1;

if(!fl[1]) Insert(1);
F[1]=ans1-sgt.query(1,1,m);
if(!fl[1]) Delete(1);

dfs1(1,0,0);

for(int i=1;i<=n;i++) cout<<F[i]<<'\n';
return 0;
}

posted @ 2023-09-23 17:30  Binary_Lee  阅读(43)  评论(0编辑  收藏  举报
Title