• CodeForces


    Mitya and Vasya are playing an interesting game. They have a rooted tree with n vertices, and the vertices are indexed from 1 to n. The root has index 1. Every other vertex i2 has its parent pi, and vertex i is called a child of vertex pi

    .

    There are some cookies in every vertex of the tree: there are xi

    cookies in vertex i. It takes exactly ti time for Mitya to eat one cookie in vertex i. There is also a chip, which is initially located in the root of the tree, and it takes li time to move the chip along the edge connecting vertex i

    with its parent.

    Mitya and Vasya take turns playing, Mitya goes first.

    • Mitya moves the chip from the vertex, where the chip is located, to one of its children.
    • Vasya can remove an edge from the vertex, where the chip is located, to one of its children. Vasya can also decide to skip his turn.

    Mitya can stop the game at any his turn. Once he stops the game, he moves the chip up to the root, eating some cookies along his way. Mitya can decide how many cookies he would like to eat in every vertex on his way. The total time spent on descend, ascend and eating cookies should not exceed T

    . Please note that in the end of the game the chip is always located in the root of the tree: Mitya can not leave the chip in any other vertex, even if he has already eaten enough cookies — he must move the chip back to the root (and every move from vertex v to its parent takes lv

    time).

    Find out what is the maximum number of cookies Mitya can eat, regardless of Vasya's actions.

    Input

    The first line contains two integers n

    and T — the number of vertices in the tree and the time he has to accomplish his task (2n105; 1T1018

    ).

    The second line contains n

    integers x1, x2, ..., xn — number of cookies located in the corresponding vertex (1xi106). The third line contains n integers t1, t2, ..., tn — how much time it takes Mitya to eat one cookie in vertex i (1ti106

    ).

    Each of the following n1

    lines describe the tree. For every i from 2 to n, the corresponding line contains two integers pi and li, where pi denotes the parent of vertex i and li denotes the time it takes Mitya to move the chip along the edge from vertex i to its parent (1pi<i, 0li109

    ).

    Output

    Output a single integer — maximum number of cookies Mitya can eat.

    Examples

    Input
    5 26
    1 5 1 7 7
    1 3 2 2 2
    1 1
    1 1
    2 0
    2 0
    
    Output
    11
    
    Input
    3 179
    2 2 1
    6 6 6
    1 3
    2 3
    
    Output
    4
    

    Note

    In the first example test case, Mitya can start by moving the chip to vertex 2

    . In this case no matter how Vasya plays, Mitya is able to eat at least 11

    cookies. Below you can find the detailed description of the moves:

    1. Mitya moves chip to vertex 2
    • .
    • Vasya removes edge to vertex 4
    • .
    • Mitya moves chip to vertex 5
    • .
    • Since vertex 5
    • has no children, Vasya does not remove any edges.
    • Mitya stops the game and moves the chip towards the root, eating cookies along the way (7

    in vertex 5, 3 in vertex 2, 1 in vertex 1

    1. ).

    Mitya spend 1+0

    time to go down, 0+1 to go up, 72 to eat 7 cookies in vertex 5, 33 to eat 3 cookies in vertex 2, 11 to eat 1 cookie in vertex 1. Total time is 1+0+0+1+72+33+11=26.

    题意:给定带权树,每个节点有一些a[i]个吃的,每个需要时间t[i],现在让你找一条路线,可以吃到最多的吃的。

    思路:对于当前路线1-u,减去路上花费的时间,剩下的时间T-time用来吃东西,我们肯定是按照时间t排序后从小到大吃,这里不嫩想到用二分+前缀和来做。

    线段树可以很好的解决这个问题。 (参考了WXK的代码,非常的漂亮,orz

    题目还有博弈的限制,其实就是除了1号节点找第二大即可。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=4000010;
    ll sum[maxn],num[maxn],Mx[maxn][2],ans[maxn];int t[maxn],x[maxn];
    int Laxt[maxn],Next[maxn],To[maxn],Len[maxn<<1],cnt;
    void add(int u,int v,int l){
        Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; Len[cnt]=l;
    }
    void update(int Now,int L,int R,int pos,int val)
    {
        sum[Now]+=(ll)val*pos; num[Now]+=val;
        if(L==R) return ;int Mid=(L+R)>>1;
        if(pos<=Mid) update(Now<<1,L,Mid,pos,val);
        else update(Now<<1|1,Mid+1,R,pos,val);
    }
    ll query(int Now,int L,int R,ll T)
    {
        if(sum[Now]<=T) return num[Now];
        if(L==R) return T/L;
        int Mid=(L+R)>>1;
        if(sum[Now<<1]<=T) return num[Now<<1]+query(Now<<1|1,Mid+1,R,T-sum[Now<<1]);
        return query(Now<<1,L,Mid,T);
    }
    void dfs(int u,ll T)
    {
        if(T<=0) return ;
        update(1,1,1000000,t[u],x[u]);
        ans[u]=query(1,1,1000000,T);
        for(int i=Laxt[u];i;i=Next[i]){
            dfs(To[i],T-Len[i]*2);
            ll z=ans[To[i]];
            if(z>Mx[u][1]) swap(z,Mx[u][1]);
            if(z>Mx[u][0]) swap(z,Mx[u][0]);
        }
        if(u!=1) ans[u]=max(Mx[u][0],ans[u]);
        else ans[u]=max(Mx[u][1],ans[u]);
        update(1,1,1000000,t[u],-x[u]);
    }
    int main()
    {
        int N,p,l; ll T;
        scanf("%d%lld",&N,&T);
        rep(i,1,N) scanf("%d",&x[i]);
        rep(i,1,N) scanf("%d",&t[i]);
        rep(i,2,N){
            scanf("%d%d",&p,&l);
            add(p,i,l);
        }
        dfs(1,T);
        printf("%lld
    ",ans[1]);
        return 0;
    }
  • 相关阅读:
    001.Git简介与安装
    004.MySQL主库手动复制至从库
    001.MySQL高可用主从复制简介
    SQL Server之索引解析(一)
    设计模式之简单工厂模式
    设计模式之总体介绍
    .NET Framework与.NET Core
    【python opencv】二维直方图
    【python opencv】直方图均衡
    【python opencv】直方图查找、绘制和分析
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10230667.html
Copyright © 2020-2023  润新知