Codeforces Round #530 (Div. 2) 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\n", ans[1]); return 0; } /* */