• Codeforces Round #530 (Div. 2) F


    F - Cookies

    思路:我们先考虑如何算出在每个节点结束最多能吃多少饼干, 这个dfs的时候用线段树维护一下就好了,

    然后有个这个信息之后树上小dp一下就好啦。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    
    using namespace std;
    
    const int N = 1e6 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-5;
    const double PI = acos(-1);
    
    LL n, T, t[N], cnt[N], dp[N], ans[N];
    vector<PLI> G[N];
    
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    LL a[N<<2], sum[N<<2];
    void update(int p, LL val, int l=1, int r=1000000, int rt=1) {
        if(l == r) {
            a[rt] += val;
            sum[rt] += val*p;
            return;
        }
        int mid = l + r >> 1;
        if(p <= mid) update(p, val, lson);
        else update(p, val, rson);
        a[rt] = a[rt<<1] + a[rt<<1|1];
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    LL query(LL res, int l=1, int r=1000000, int rt=1) {
        if(sum[rt] <= res) return a[rt];
        if(l == r) return res / l;
        int mid = l + r >> 1;
        if(res <= sum[rt<<1]) return query(res, lson);
        else return query(sum[rt<<1], lson) + query(res-sum[rt<<1], rson);
    }
    
    void getDp(int u, LL res) {
        update(t[u], cnt[u]);
        dp[u] = query(res);
        for(auto e : G[u]) getDp(e.se, res-e.fi);
        update(t[u], -cnt[u]);
    }
    
    void dfs(int u) {
        ans[u] = dp[u];
        if(u == 1) {
            LL mx = 0;
            for(auto e : G[u]) dfs(e.se), mx = max(mx, ans[e.se]);
            ans[u] = max(ans[u], mx);
        } else {
            LL mx = 0, mx2 = 0;
            for(auto e : G[u]) {
                dfs(e.se);
                if(ans[e.se] >= mx) mx2 = mx, mx = ans[e.se];
                else if(ans[e.se] > mx2) mx2 = ans[e.se];
            }
            ans[u] = max(ans[u], mx2);
        }
    }
    
    int main() {
        cin >> n >> T;
        for(int i = 1; i <= n; i++) cin >> cnt[i];
        for(int i = 1; i <= n; i++) cin >> t[i];
        for(int i = 2; i <= n; i++) {
            LL p, l; cin >> p >> l;
            G[p].push_back(mk(l<<1, i));
        }
        getDp(1, T);
        dfs(1);
        printf("%lld
    ", ans[1]);
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    JS——switch case
    JS——“==”与“===”
    C#——枚举格式转换与比较
    XML——读与写
    SQl基本操作——try catch
    JS——indexOf replace search
    C#——数据库的访问
    SQL基本操作——存储过程
    C#——设置开机启动
    C#——计时器的操作
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10233303.html
Copyright © 2020-2023  润新知