bzoj3011 可并堆

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3011 可并堆相关的知识,希望对你有一定的参考价值。

我们可以遍历得出每个节点到根节点的距离h,然后用可并堆进行维护。树形dp

我用的是pairing heap

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<queue>
 4 using namespace std ; 
 5 
 6 struct node {
 7     long long value ;
 8     node * brother ; 
 9     node * child ; 
10     node ( const long long value ) : value ( value ) , 
11     brother ( 0 ) , child ( 0 ) {} ;
12 } ;
13 
14 node * merge ( node * a , node * b ) {
15     if ( a == 0 ) return b ; 
16     if ( b == 0 ) return a ;
17     if ( a -> value < b -> value ) swap ( a , b ) ; 
18     b -> brother = a -> child ; 
19     a -> child = b ; 
20     a -> brother = 0 ;
21     return a ;
22 }
23 
24 node * pop ( node * a ) {
25     node * o = a -> child ; 
26     delete a ; 
27     if ( o == 0 ) return 0 ;
28     static queue < node * > q ; 
29     while ( ! q . empty () ) q . pop () ;
30     while ( o ) {
31         q . push ( o ) ; 
32         o = o -> brother ; 
33     }
34     while ( q . size () > 1u ) {
35         node * a = q . front () ; 
36         q . pop () ; 
37         node * b = q . front () ; 
38         q . pop () ; 
39         q . push ( merge ( a , b ) ) ;
40     }
41     return q . front () ; 
42 }
43 
44 
45 const int MAXN = 200000 + 20 ; 
46 int pa [ MAXN ] ;
47 long long l [ MAXN ] ;
48 long long h [ MAXN ] ;
49 int size [ MAXN ] ;
50 int N ;
51 long long L ;
52 node * heap [ MAXN ] ;
53 
54 int main () {
55     scanf ( "%d%lld" , & N , & L ) ; 
56     for ( int i = 2 ; i <= N ; ++ i ) 
57         scanf ( "%d%lld" , & pa [ i ] , & l [ i ] ) ; 
58     for ( int i = 2 ; i <= N ; ++ i ) h [ i ] = l [ i ] + h [ pa [ i ] ] ;
59     for ( int i = 1 ; i <= N ; ++ i ) {
60         heap [ i ] = new node ( h [ i ] ) ; 
61         size [ i ] = 1 ; 
62     }
63     for ( int i = N ; i >= 2 ; -- i ) {
64         while ( heap [ i ] -> value - h [ i ] > L ) {
65             heap [ i ] = pop ( heap [ i ] ) ; 
66             size [ i ] -- ; 
67         }
68         heap [ pa [ i ] ] = merge ( heap [ pa [ i ] ] , heap [ i ] ) ; 
69         size [ pa [ i ] ] += size [ i ] ;
70     }
71     while ( heap [ 1 ] -> value - h [ 1 ] > L ) {
72         heap [ 1 ] = pop ( heap [ 1 ] ) ; 
73         size [ 1 ] -- ; 
74     }
75     for ( int i = 1 ; i <= N ; ++ i ) 
76         printf ( "%d\n" , size [ i ] ) ; 
77     return 0 ; 
78 }

 

以上是关于bzoj3011 可并堆的主要内容,如果未能解决你的问题,请参考以下文章

bzoj2806 [Apio2012]dispatching可并堆

[可并堆] Bzoj P1367 sequence

[BZOJ 2333] 棘手的操作 可并堆

BZOJ3252: 攻略 可并堆

[BZOJ2809][Apio2012]dispatching 贪心+可并堆

bzoj1367[Baltic2004]sequence 可并堆