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;
}

/*
*/
原文地址:https://www.cnblogs.com/CJLHY/p/10233303.html