1 条题解

  • 1
    @ 2022-7-21 21:14:38
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int N=2e5+3,M=4e6+3;
    int rt[N*3],n,he[N],ne[N],p[N],o[N],t[M],lc[M],rc[M],c[N],id,u,v,w,m;
    ll s[N],q[N],l[N],d[N],f[N],a[N],b[N];
    #define g(t,x) (a[t]*(x)+b[t])
    void tupd(int&k,int l,int r){//李超树插入直线(动态开点)
    	if(k){
    		int m=l+r>>1;
    		if(g(w,m)<g(t[k],m))swap(w,t[k]);
    		if(l<r)a[w]<a[t[k]]?tupd(rc[k],m+1,r):tupd(lc[k],l,m);
    	}else t[k=++id]=w;
    }
    ll tqry(int k,int l,int r){//李超树查询最小值
    	if(!k)return 1e18;
    	int m=l+r>>1;
    	return min(g(t[k],w),w>m?tqry(rc[k],m+1,r):tqry(lc[k],l,m));
    }
    void upd(int k,int l,int r){//外层线段树单点修改
    	w=v,tupd(rt[k],0,1e6);
    	if(l==r)return;
    	int m=l+r>>1;
    	u>m?upd(k*2+1,m+1,r):upd(k*2,l,m);
    }
    ll qry(int k,int l,int r){//外层线段树区间查询
    	if(u<=l&&r<=v)return tqry(rt[k],0,1e6);
    	int m=l+r>>1;
    	return u>m?qry(k*2+1,m+1,r):(m<v?min(qry(k*2,l,m),qry(k*2+1,m+1,r)):qry(k*2,l,m));
    }
    void pre(int x){//预处理出栈序
    	for(int i=he[x];i;i=ne[i])pre(i);
    	o[x]=++id;
    }
    void dfs(int x){
    	a[x]=-d[m],b[x]=f[x],u=o[v=c[m]=x],upd(1,1,n);
    	for(int i=he[x];i;i=ne[i]){
    		++m,d[m]=d[m-1]+s[i],u=o[i],v=o[c[lower_bound(d,d+m,d[m]-l[i])-d]];
    		w=p[i],f[i]=qry(1,1,n)+d[m]*w+q[i],dfs(i),--m;
    	}
    }
    int main(){
    	int i,j;
    	scanf("%d%*d",&n);
    	for(i=2;i<=n;++i)scanf("%d%lld%d%lld%lld",&j,s+i,p+i,q+i,l+i),ne[i]=he[j],he[j]=i;
    	pre(1),id=0,dfs(1);
    	for(i=2;i<=n;++i)printf("%lld\n",f[i]);
    	return 0;
    }
    
    • 1

    信息

    ID
    131
    时间
    3000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    5
    已通过
    4
    上传者