# [UOJ UR #4追击圣诞老人]

#include<iostream>
#include<cstdio>
#include<queue>
#define MN 500000
#define N 524288
#define ll long long
using namespace std;
{
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 data{int x,y;ll X;
friend bool operator <(const data&x,const data&y){return x.X>y.X;}
data operator + (ll y)
{
data c=*this;c.X+=y;
return c;
}
};
priority_queue<data> q;
int s[MN+5],p[MN+5],fa[MN+5],T[N*2+5],dfn[MN+5],dn=0;
struct edge{int to,next;}e[MN+5];
vector<data>v[MN+5];
int Merge(int x,int y){return w[x]>w[y]?y:x;}
int query(int l,int r)
{
int sum=0;
for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
{
if(~l&1) sum=Merge(sum,T[l+1]);
if( r&1) sum=Merge(sum,T[r-1]);
}
return sum;
}
inline int Up(int x,int k)
{
int z=dep[x]-k;
for(;dep[top[x]]>z;x=fa[top[x]]);
return p[dfn[top[x]]+z-dep[top[x]]];
}
int lca(int x,int y)
{
for(;top[x]!=top[y];x=fa[top[x]])
if(dep[top[x]]<dep[top[y]]) swap(x,y);
return dep[x]<dep[y]?x:y;
}

pair<int,int> Query(int x,int y)
{
int res=0;
for(;top[x]!=top[y];x=fa[top[x]])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res=Merge(res,s[x]);
}
if(dfn[x]>dfn[y]) swap(x,y);
res=Merge(res,query(dfn[x],dfn[y]));
return make_pair(x,res);
}

data Insert(int x,int y,ll v)
{
//    cout<<"Insert"<<x<<" "<<y<<" "<<v<<endl;
pair<int,int> z=Query(x,y);
//    cout<<"CalcOK"<<z.first<<" "<<z.second<<endl;
return (data){x,y,w[z.second]}+v;
}

void Solve(int x,int y,int z,int l,ll Add)
{
//    cout<<"Solve"<<x<<" "<<y<<" "<<z<<" "<<l<<" "<<Add<<endl;
if(z==l)
{
return;
}
if(!(dep[x]>=dep[z]&&Up(x,dep[x]-dep[z])==z)) swap(x,y);
}

void Dfs(int x,int tp)
{
top[x]=tp;p[dfn[x]=++dn]=x;
if(tp==x) s[x]=x; else s[x]=Merge(s[fa[x]],x);
if(mx[x]) Dfs(mx[x],tp);
if(e[i].to!=mx[x]) Dfs(e[i].to,e[i].to);
}

void Pre(int x)
{
top[x]=1;mx[x]=0;
{
Pre(e[i].to);
top[x]+=top[e[i].to];
if(top[e[i].to]>top[mx[x]]) mx[x]=e[i].to;
}
}

int main()
{
Pre(1);Dfs(1,1);
for(int i=1;i<=n;++i) T[i+N]=p[i];
for(int i=N;i;--i) T[i]=Merge(T[i<<1],T[i<<1|1]);
for(int i=1;i<=n;++i)
{
if(x==y&&y==z){v[i].push_back((data){x,x,w[x]});continue;}
if(x==y) swap(x,z);v[i].push_back(Insert(x,y,0));
if(z==y||z==x) continue;
int l1=lca(x,z),l2=lca(y,z),L=lca(x,y);
if(dep[z]<dep[L]) v[i].push_back(Insert(fa[L],z,0));
else if(z!=l1&&z!=l2)
{
if(dep[l1]<dep[l2]) swap(l1,l2);
int Z=Up(z,dep[z]-dep[l1]-1);
v[i].push_back(Insert(z,Z,0));
}
}
for(int i=1;i<=k;++i)
{
data x=q.top();q.pop();printf("%lld\n",x.X);int z=Query(x.x,x.y).second;
//printf("%d %d %d %d %lld\n",x.x,x.y,x.l,x.z,x.X);
Solve(x.x,x.y,z,lca(x.x,x.y),x.X-w[z]);
for(int j=0;j<v[z].size();++j) q.push(v[z][j]+x.X);
}
return 0;
}

posted @ 2017-09-12 23:18  FallDream  阅读(437)  评论(0编辑  收藏  举报