P2305 1pts求助,只过了hack
  • 板块题目总版
  • 楼主Zi_Gao
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/2/26 17:32
  • 上次更新2023/10/23 23:40:24
查看原帖
P2305 1pts求助,只过了hack
554698
Zi_Gao楼主2023/2/26 17:32

思想:dfs遍历树,过程中维护根节点到当前节点的一条链,进行斜率优化dp

#include<cstdio>
#include<cstring>
#define ONLINE_JUDGE
#define int long long
#define INPUT_DATA_TYPE long long
#define OUTPUT_DATA_TYPE long long
INPUT_DATA_TYPE read(){register INPUT_DATA_TYPE x=0;register char f=0,c=getchar();while(c<'0'||'9'<c)f=(c=='-'),c=getchar();while('0'<=c&&c<='9')x=(x<<3)+(x<<1)+(c&15),c=getchar();return f?-x:x;}void print(OUTPUT_DATA_TYPE x){register char stack[20];register int i=0;if(x<0){x=-x;putchar('-');}if(x==0){putchar('0');return;}while(x){stack[i++]=x%10;x/=10;}while(i){putchar(stack[--i]+'0');}return;}

struct EDGE{
    int to,next;
    long long w;
    EDGE(){
        next=-1;
        return;
    }
}e[200010];

int tot,head,tail,top,path[200010],fir[200010],Q[200010],stack[200010];
long long sum[200010],p[200010],q[200010],l[200010],dp[200010];

void addEdge(int u,int v,long long w){
    e[tot].to=v;
    e[tot].w=w;
    e[tot].next=fir[u];
    fir[u]=tot;
    ++tot;
    return;
}

long long Y(int j){return dp[path[j]];}
long long X(int j){return sum[j];}
long long K(int i){return p[path[i]];}
long long B(int i){return -sum[i]*p[path[i]]-q[path[i]];}
bool checkslope(int a,int b,long long k){return Y(a)-Y(b)>=k*(X(a)-X(b));}
bool check(int a,int b,int c,int d){return (Y(a)-Y(b))*(X(c)-X(d))<=(Y(c)-Y(d))*(X(a)-X(b));}

int searchPoint(register int l,register int r,long long k){
    if(l==r) return l;
    register int mid;
    while(l<r){
        mid=(l+r)>>1;
        if(checkslope(Q[mid],Q[mid+1],k)) l=mid+1;
        else r=mid;
    }
    return l;
}

int searchHead(register int l,register int r,long long k){
    if(l==r) return l;
    register int mid;
    while(l<r){
        mid=(l+r)>>1;
        if(sum[Q[mid]]<k) l=mid+1;
        else r=mid;
    }
    return l;
}

void dfs(int u,int i){
    int ctop=0;
    register int j;
    path[i]=u;
    if(u==1){
        dp[i]=0;
        head=tail=1;
        Q[head]=1;
    }else{
        ctop=top;
        head=searchHead(1,tail+1,sum[i]-l[u]);
        int point=searchPoint(head,tail,K(i));
        dp[u]=Y(Q[point])-K(i)*X(Q[point])-B(i);
        while(head<tail&&check(Q[tail],i,Q[tail-1],Q[tail])){
            stack[top++]=Q[tail];
            --tail;
        }
        Q[++tail]=i;
    }
    for(j=fir[u];~j;j=e[j].next){
        sum[i+1]=sum[i]+e[j].w;
        dfs(e[j].to,i+1);
    }
    --tail;
    while(top>ctop){
        Q[++tail]=stack[--top];
    }
    return;
}

signed main(){
	#ifndef ONLINE_JUDGE
	freopen("name.in", "r", stdin);
	freopen("name.out", "w", stdout);
	#endif

    memset(fir,-1,sizeof(fir));
    register int i,t;
    register long long t2;
    int n=read();
    int T=read();
    for(i=2;i<=n;++i){
        t=read();
        t2=read();
        addEdge(t,i,t2);
        p[i]=read();
        q[i]=read();
        l[i]=read();
    }

    dfs(1,1);

    for(i=2;i<=n;++i){
        print(dp[i]);
        putchar('\n');
    }

	#ifndef ONLINE_JUDGE
	fclose(stdin);
	fclose(stdout);
	#endif
    return 0;
}
2023/2/26 17:32
加载中...