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 }
View Code

 

posted @ 2015-06-12 17:24  idy002  阅读(208)  评论(0编辑  收藏  举报