bzoj2806 [Apio2012]dispatching【可并堆】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2809
保存可并堆模版代码。
#include <cstdio> #include <cstring> #include <algorithm> const int maxn = 100005, maxm = 1000000005; int n, m, fa[maxn], salary[maxn], lead[maxn]; int key[maxn], left[maxn], right[maxn], npl[maxn], cnt, siz[maxn]; int head[maxn], to[maxn], next[maxn], lb; long long s[maxn], ans; inline void ist(int aa, int ss) { to[lb] = ss; next[lb] = head[aa]; head[aa] = lb; ++lb; } int merge(int A, int B) { if (!A) { return B; } if (!B) { return A; } if (key[B] > key[A]) { std::swap(A, B); } right[A] = merge(right[A], B); if (npl[right[A]] > npl[left[A]]) { std::swap(left[A], right[A]); } npl[A] = npl[right[A]] + 1; s[A] = s[left[A]] + s[right[A]] + key[A]; siz[A] = siz[left[A]] + siz[right[A]] + 1; return A; } int dfs(int r) { int rt = ++cnt, tr = -666; key[rt] = salary[r]; s[rt] = salary[r]; siz[rt] = 1; for (int j = head[r]; j != -1; j = next[j]) { tr = dfs(to[j]); rt = merge(rt, tr); } while (s[rt] > m) { rt = merge(left[rt], right[rt]); } ans = std::max(ans, (long long)lead[r] * (long long)siz[rt]); return rt; } int main(void) { //freopen("in.txt", "r", stdin); memset(head, -1, sizeof head); memset(next, -1, sizeof next); npl[0] = -1; scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) { scanf("%d%d%d", fa + i, salary + i, lead + i); ist(fa[i], i); } dfs(1); printf("%lld\n", ans); return 0; }