记录编号 231762 评测结果 AAAAAAAAAA
题目名称 [NOI 2014]购票 最终得分 100
用户昵称 Gravatarstdafx.h 是否通过 通过
代码语言 C++ 运行时间 12.236 s
提交时间 2016-02-27 18:56:59 内存使用 18.56 MiB
显示代码纯文本
#define maxn 200010ul

#define lson l,mid,t
#define rson mid+1,r,t|1

#define double_type(e) ((double)((e)))

#define ll long long

#include <vector>
#include <math.h>
#include <stdio.h>

struct pii{ll x,y;};
struct Edge{int v,nx;ll w;}edge[maxn];

typedef std::vector<pii> hull;
const double inf=1ll<<62ll,eps=1e-6;
int n,case_type,ec,dfs_clock,dfn[maxn],top[maxn],rev[maxn],fa[maxn],headlist[maxn],siz[maxn],son[maxn];
ll curp,f[maxn],dis[maxn],len[maxn],pi[maxn],qi[maxn];
hull tree[maxn*3];

//f[i]=min{f[j]-dis[j]*p[i]}+dis[i]*p[i]+q[i]

void Add_Edge(int u,int v,ll w){
	edge[++ec].v=v;
	edge[ec].w=w;
	edge[ec].nx=headlist[u];
	headlist[u]=ec;
	return;
}

void dfs1(int p){
	siz[p]=1;
	for(int i=headlist[p];i;i=edge[i].nx){
		dis[edge[i].v]=dis[p]+edge[i].w,dfs1(edge[i].v);
		siz[p]+=siz[edge[i].v];
		if(!son[p]||siz[edge[i].v]>siz[son[p]]) son[p]=edge[i].v;
	}
    return;
}

void dfs2(int p,int tp){
	dfn[p]=++dfs_clock,top[p]=tp,rev[dfs_clock]=p;
	if(son[p]) dfs2(son[p],tp);
	for(int i=headlist[p];i;i=edge[i].nx){
		if(edge[i].v==son[p]) continue;
		dfs2(edge[i].v,edge[i].v);
	}
	return;
}

double slope(pii a,pii b){
	if(a.y==b.y) return inf;
	return double_type(a.x-b.x)/double_type(a.y-b.y);
}

void add(hull &v,ll ins_f,ll ins_d){
	pii p=(pii){ins_f,ins_d},x,y;
	while(v.size()>1){
		x=v[v.size()-2],y=v[v.size()-1];
		if(slope(x,y)<slope(y,p)+eps) break;
		v.pop_back();
	}
	v.push_back(p);
	return;
}

void ins(int l,int r,int rt,int pos,ll ins_f,ll ins_d){
	add(tree[rt],ins_f,ins_d);
	if(l==r) return;
	int mid=(l+r)>>1,t=rt<<1;
	if(pos<=mid) ins(lson,pos,ins_f,ins_d);
	else ins(rson,pos,ins_f,ins_d);
	return;
}

ll Min(ll a,ll b){
	return a<b?a:b;
}

ll Max(ll a,ll b){
	return a>b?a:b;
}

ll get(hull &v){
	int size_=v.size(),l=0,r=size_-1,mid,fr;
	if(!size_) return inf;
	ll ans=inf;
	v.push_back((pii){inf,v[r].y});
	while(l<=r){
		mid=(l+r)>>1;
		if(slope(v[mid],v[mid+1])+eps>=curp) fr=mid,r=mid-1;
		else l=mid+1;
	}
	ans=v[fr].x-curp*v[fr].y,v.pop_back();
	return ans;
}

ll query(int l,int r,int rt,int posl,int posr,ll lim){
	if(lim<0) return inf;
	int mid=(l+r)>>1,t=rt<<1;
	ll ans1=inf,ans2=inf;
	int st=rev[l],ed=rev[r],rm=rev[mid];
	if(posl==l&&posr==r){
		if(dis[ed]-dis[st]<=lim) return get(tree[rt]);
		ans1=query(rson,mid+1,posr,lim);
		lim-=dis[ed]-dis[rm];
		ans2=query(lson,posl,mid,lim);
		return Min(ans1,ans2);
	}
	if(posr>mid) ans1=query(rson,Max(mid+1,posl),posr,lim);
	if(posl<=mid){
		if(posr>mid) lim-=dis[rev[posr]]-dis[rm];
		ans2=query(lson,posl,Min(posr,mid),lim);
	}
	return Min(ans1,ans2);
}

ll work(int x){
	curp=pi[x];
	ll ans=(ll)inf,dis_lim=len[x],ret;
	while(x&&dis_lim>=0){
		ret=query(1,n,1,dfn[top[x]],dfn[x],dis_lim);
		if(ret<ans) ans=ret;
		dis_lim-=dis[x]-dis[fa[top[x]]];
		x=fa[top[x]];
	}
	return ans;
}

ll read(){
	ll x=0,c=getchar();
	while(c<'0'||c>'9') c=getchar();
	for(;c>='0'&&c<='9';c=getchar()) x=(x<<1ll)+(x<<3ll)+(c^48ll);
	return x;
}

int main(){
	freopen("ticket.in","r",stdin);
	freopen("ticket.out","w",stdout);
	n=read(),case_type=read();ll w;
	for(int i=2;i<=n;i++){
		fa[i]=read(),w=read(),pi[i]=read(),qi[i]=read(),len[i]=read();
		Add_Edge(fa[i],i,w);
	}
	dfs1(1),dfs2(1,1),ins(1,n,1,1,0,0);
	for(int i=2,x;i<=n;i++){
        x=rev[i],f[x]=work(x)+dis[x]*pi[x]+qi[x];
		ins(1,n,1,dfn[x],f[x],dis[x]);
	}
	for(int i=2;i<=n;i++) printf("%lld\n",f[i]);
	return 0;
}