bzoj 2809 可并堆维护子树信息
对于每个节点,要在其子树中选尽量多的节点,并且节点的权值和小于一个定值.
建立大根堆,每个节点从儿子节点合并,并弹出最大值直到和满足要求.
1 /************************************************************** 2 Problem: 2809 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:1224 ms 7 Memory:6664 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 #define max(a,b) ((a)>(b)?(a):(b)) 13 #define N 100010 14 using namespace std; 15 16 typedef long long dnt; 17 18 #define szof(nd) ((nd)?(nd)->sz:0) 19 struct Node { 20 int v, sz; 21 dnt s; 22 Node *ls, *rs; 23 inline void update() { 24 s = v + (ls?ls->s:0) + (rs?rs->s:0); 25 sz = 1 + szof(ls) + szof(rs); 26 if( szof(ls)<szof(rs) ) swap(ls,rs); 27 } 28 }pool[N], *tail=pool, *root[N]; 29 30 int n, m; 31 int head[N], dest[N], next[N], etot; 32 dnt lead[N], cost[N]; 33 int qu[N], bg, ed, master; 34 35 void adde( int u, int v ) { 36 etot++; 37 dest[etot] = v; 38 next[etot] = head[u]; 39 head[u] = etot; 40 } 41 Node *newnode( int v ) { 42 Node *nd = ++tail; 43 nd->s = nd->v = v; 44 nd->ls = nd->rs = 0; 45 nd->sz = 1; 46 return nd; 47 } 48 Node *smerge( Node *na, Node *nb ) { 49 if( !na && !nb ) return 0; 50 if( !na ) return nb; 51 if( !nb ) return na; 52 if( na->v > nb->v ) { 53 na->rs = smerge( na->rs, nb ); 54 na->update(); 55 return na; 56 } else { 57 nb->rs = smerge( nb->rs, na ); 58 nb->update(); 59 return nb; 60 } 61 } 62 int main() { 63 scanf( "%d%d", &n, &m ); 64 for( int i=1,p; i<=n; i++ ) { 65 scanf( "%d%lld%lld", &p, cost+i, lead+i ); 66 if( p ) adde( p, i ); 67 else master = i; 68 } 69 qu[bg=ed=1] = master; 70 while( bg<=ed ) { 71 int u=qu[bg++]; 72 for( int t=head[u]; t; t=next[t] ) { 73 int v=dest[t]; 74 qu[++ed] = v; 75 } 76 } 77 dnt ans = 0; 78 for( int i=ed; i>=1; i-- ) { 79 int u=qu[i]; 80 root[u] = newnode(cost[u]); 81 for( int t=head[u]; t; t=next[t] ) { 82 int v=dest[t]; 83 root[u] = smerge( root[u], root[v] ); 84 } 85 while( root[u]->s > m ) 86 root[u] = smerge( root[u]->ls, root[u]->rs ); 87 ans = max( ans, lead[u]*root[u]->sz ); 88 } 89 printf( "%lld\n", ans ); 90 }