您的位置:首页 > 其它

bzoj3011 可并堆

2016-03-31 15:11 337 查看
我们可以遍历得出每个节点到根节点的距离h,然后用可并堆进行维护。树形dp

我用的是pairing heap

#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std ;

struct node {
long long value ;
node * brother ;
node * child ;
node ( const long long value ) : value ( value ) ,
brother ( 0 ) , child ( 0 ) {} ;
} ;

node * merge ( node * a , node * b ) {
if ( a == 0 ) return b ;
if ( b == 0 ) return a ;
if ( a -> value < b -> value ) swap ( a , b ) ;
b -> brother = a -> child ;
a -> child = b ;
a -> brother = 0 ;
return a ;
}

node * pop ( node * a ) {
node * o = a -> child ;
delete a ;
if ( o == 0 ) return 0 ;
static queue < node * > q ;
while ( ! q . empty () ) q . pop () ;
while ( o ) {
q . push ( o ) ;
o = o -> brother ;
}
while ( q . size () > 1u ) {
node * a = q . front () ;
q . pop () ;
node * b = q . front () ;
q . pop () ;
q . push ( merge ( a , b ) ) ;
}
return q . front () ;
}

const int MAXN = 200000 + 20 ;
int pa [ MAXN ] ;
long long l [ MAXN ] ;
long long h [ MAXN ] ;
int size [ MAXN ] ;
int N ;
long long L ;
node * heap [ MAXN ] ;

int main () {
scanf ( "%d%lld" , & N , & L ) ;
for ( int i = 2 ; i <= N ; ++ i )
scanf ( "%d%lld" , & pa [ i ] , & l [ i ] ) ;
for ( int i = 2 ; i <= N ; ++ i ) h [ i ] = l [ i ] + h [ pa [ i ] ] ;
for ( int i = 1 ; i <= N ; ++ i ) {
heap [ i ] = new node ( h [ i ] ) ;
size [ i ] = 1 ;
}
for ( int i = N ; i >= 2 ; -- i ) {
while ( heap [ i ] -> value - h [ i ] > L ) {
heap [ i ] = pop ( heap [ i ] ) ;
size [ i ] -- ;
}
heap [ pa [ i ] ] = merge ( heap [ pa [ i ] ] , heap [ i ] ) ;
size [ pa [ i ] ] += size [ i ] ;
}
while ( heap [ 1 ] -> value - h [ 1 ] > L ) {
heap [ 1 ] = pop ( heap [ 1 ] ) ;
size [ 1 ] -- ;
}
for ( int i = 1 ; i <= N ; ++ i )
printf ( "%d\n" , size [ i ] ) ;
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: