【HDU】5002 Tree 动态树模板题

来源:互联网 发布:淘宝购物车登陆 编辑:程序博客网 时间:2024/04/30 12:23

传送门:【HDU】5002 Tree


题目分析:终于做出来啦~~~~

LCT模板题啊,不过还是很开心~


维护好set标记,add标记,flip标记,维护好最大值,第二大值,以及相应的出现次数就好了~


不过我的LCT效率不高,应该是更新的时候姿势不对,我再去优化优化~


代码如下:


#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std ;typedef long long LL ;#define rep( i , a , b ) for ( int i = a ; i < b ; ++ i )#define For( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define rev( i , a , b ) for ( int i = a ; i >= b ; -- i )#define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )#define clr( a , x ) memset ( a , x , sizeof a )#define cpy( a , x ) memcpy ( a , x , sizeof a )#define ls ( o << 1 )#define rs ( o << 1 | 1 )#define lson ls , l , m#define rson rs , m + 1 , r#define mid ( ( l + r ) >> 1 )#define root 1 , 1 , nconst int MAXN = 100005 ;const int INF = 0x3f3f3f3f ;struct Node* null ;struct Node {Node* c[2] ;Node* f ;int size ;int mmax ;int smax ;int mmax_num ;int smax_num ;int v ;int flip ;int addv ;int setv ;void newnode ( int val ) {v = val ;mmax = val ;smax = -INF ;mmax_num = 1 ;smax_num = 0 ;size = 1 ;flip = 0 ;addv = 0 ;setv = -INF ;f = c[0] = c[1] = null ;}void add_val ( int val ) {if ( this == null ) return ;addv += val ;v += val ;mmax += val ;if ( smax != -INF ) smax += val ;}void set_val ( int val ) {if ( this == null ) return ;setv = val ;addv = 0 ;v = val ;mmax = val ;smax = -INF ;mmax_num = size ;smax_num = 0 ;}void reverse () {if ( this == null ) return ;swap ( c[0] , c[1] ) ;flip ^= 1 ;}void push_up () {size = c[0]->size + 1 + c[1]->size ;int a[5] = { v , c[0]->mmax , c[1]->mmax , c[0]->smax , c[1]->smax } ;sort ( a , a + 5 ) ;int cnt = 0 ;rep ( i , 1 , 5 ) if ( a[i] != a[cnt] ) a[++ cnt] = a[i] ;mmax = a[cnt] ;smax = a[cnt - 1] ;mmax_num = smax_num = 0 ;if ( v == mmax ) ++ mmax_num ;if ( c[0]->mmax == mmax ) mmax_num += c[0]->mmax_num ;if ( c[1]->mmax == mmax ) mmax_num += c[1]->mmax_num ;if ( smax != -INF ) {if ( v == smax ) ++ smax_num ;if ( c[0]->mmax == smax ) smax_num += c[0]->mmax_num ;if ( c[0]->smax == smax ) smax_num += c[0]->smax_num ;if ( c[1]->mmax == smax ) smax_num += c[1]->mmax_num ;if ( c[1]->smax == smax ) smax_num += c[1]->smax_num ;}}void push_down () {if ( flip ) {c[0]->reverse () ;c[1]->reverse () ;flip = 0 ;}if ( setv != -INF ) {c[0]->set_val ( setv ) ;c[1]->set_val ( setv ) ;setv = -INF ;}if ( addv ) {c[0]->add_val ( addv ) ;c[1]->add_val ( addv ) ;addv = 0 ;}}void link_child ( Node* o , int d ) {c[d] = o ;o->f = this ;}int is_root () {return f == null || this != f->c[0] && this != f->c[1] ;}void sign_down () {if ( !is_root () ) f->sign_down () ;push_down () ;}void rotate ( int d ) {Node* p = f ;Node* gp = f->f ;p->link_child ( c[d] , !d ) ;if ( !p->is_root () ) {if ( gp->c[0] == p ) gp->link_child ( this , 0 ) ;else gp->link_child ( this , 1 ) ;} else f = gp ;link_child ( p , d ) ;p->push_up () ;}void splay () {sign_down () ;while ( !is_root () ) {if ( f->is_root () ) {this == f->c[0] ? rotate ( 1 ) : rotate ( 0 ) ;} else {if ( f == f->f->c[0] ) {this == f->c[0] ? f->rotate ( 1 ) : rotate ( 0 ) ;rotate ( 1 ) ;} else {this == f->c[1] ? f->rotate ( 0 ) : rotate ( 1 ) ;rotate ( 0 ) ;}}}push_up () ;}void access () {Node* o = this ;Node* x = null ;while ( o != null ) {o->splay () ;o->link_child ( x , 1 ) ;o->push_up () ;x = o ;o = o->f ;}splay () ;}void make_root () {access () ;reverse () ;}Node* find_root () {access () ;Node* o = this ;while ( o->c[0] != null ) {o->push_down () ;o = o->c[0] ;}return o ;}void cut () {access () ;c[0]->f = null ;c[0] = null ;push_up () ;}void cut ( Node* o ) {//if ( o == this || find_root () != o->find_root () ) return ;o->make_root () ;cut () ;}void link ( Node* o ) {//if ( o == this || find_root () == o->find_root () ) return ;o->make_root () ;o->f = this ;}void add ( Node* o , int val ) {//if ( find_root () != o->find_root () ) return ;o->make_root () ;access () ;add_val ( val ) ;}void set ( Node* o , int val ) {//if ( find_root () != o->find_root () ) return ;o->make_root () ;access () ;set_val ( val ) ;}void query ( Node* o ) {//if ( find_root () != o->find_root () ) return ;o->make_root () ;access () ;if ( !smax_num ) printf ( "ALL SAME\n" ) ;else printf ( "%d %d\n" , smax , smax_num ) ;//printf ( "%d %d %d %d\n" , mmax , mmax_num , smax , smax_num ) ;}} ;Node memory_pool[MAXN] ;Node* cur ;Node* node[MAXN] ;int n , q ;void clear () {cur = memory_pool ;cur->newnode ( -INF ) ;null = cur ++ ;null->size = 0 ;}void solve () {int op , x , y , a , b , val ;clear () ;scanf ( "%d%d" , &n , &q ) ;For ( i , 1 , n ) {scanf ( "%d" , &val ) ;cur->newnode ( val ) ;node[i] = cur ++ ;}rep ( i , 1 , n ) {scanf ( "%d%d" , &x , &y ) ;node[x]->link ( node[y] ) ;}rep ( i , 0 , q ) {scanf ( "%d%d%d" , &op , &x , &y ) ;switch ( op ) {case 1 :scanf ( "%d%d" , &a , &b ) ;node[x]->cut ( node[y] ) ;node[a]->link ( node[b] ) ;break ;case 2 :scanf ( "%d" , &val ) ;node[x]->set ( node[y] , val ) ;break ;case 3 :scanf ( "%d" , &val ) ;node[x]->add ( node[y] , val ) ;break ;case 4 :node[x]->query ( node[y] ) ;break ;default : break ;}}}int main () {int T , cas = 0 ;scanf ( "%d" , &T ) ;while ( T -- ) {printf ( "Case #%d:\n" , ++ cas ) ;solve () ;}return 0 ;}

-------Update 2014.09.28--------


优化了push_up,效率快了近一倍~


代码如下:


#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std ;typedef long long LL ;#define rep( i , a , b ) for ( int i = a ; i < b ; ++ i )#define For( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define rev( i , a , b ) for ( int i = a ; i >= b ; -- i )#define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )#define clr( a , x ) memset ( a , x , sizeof a )#define cpy( a , x ) memcpy ( a , x , sizeof a )#define ls ( o << 1 )#define rs ( o << 1 | 1 )#define lson ls , l , m#define rson rs , m + 1 , r#define mid ( ( l + r ) >> 1 )#define root 1 , 1 , nconst int MAXN = 100005 ;const int INF = 0x3f3f3f3f ;struct Node* null ;struct Node {Node* c[2] ;Node* f ;int size ;int mmax ;int smax ;int mmax_num ;int smax_num ;int v ;int flip ;int addv ;int setv ;void newnode ( int val ) {v = val ;mmax = val ;smax = -INF ;mmax_num = 1 ;smax_num = 0 ;size = 1 ;flip = 0 ;addv = 0 ;setv = -INF ;f = c[0] = c[1] = null ;}void add_val ( int val ) {if ( this == null ) return ;addv += val ;v += val ;mmax += val ;if ( smax != -INF ) smax += val ;}void set_val ( int val ) {if ( this == null ) return ;setv = val ;addv = 0 ;v = val ;mmax = val ;smax = -INF ;mmax_num = size ;smax_num = 0 ;}void reverse () {if ( this == null ) return ;swap ( c[0] , c[1] ) ;flip ^= 1 ;}void update ( int val , int num ) {if ( val == -INF ) return ;if ( val < smax ) return ;if ( val > mmax ) {smax = mmax ;smax_num = mmax_num ;mmax = val ;mmax_num = num ;} else if ( val == mmax ) {mmax_num += num ;} else if ( val > smax ) {smax = val ;smax_num = num ;} else smax_num += num ;}void push_up () {size = c[0]->size + 1 + c[1]->size ;mmax = smax = -INF ;mmax_num = smax_num = 0 ;update ( v , 1 ) ;update ( c[0]->mmax , c[0]->mmax_num ) ;update ( c[0]->smax , c[0]->smax_num ) ;update ( c[1]->mmax , c[1]->mmax_num ) ;update ( c[1]->smax , c[1]->smax_num ) ;}void push_down () {if ( flip ) {c[0]->reverse () ;c[1]->reverse () ;flip = 0 ;}if ( setv != -INF ) {c[0]->set_val ( setv ) ;c[1]->set_val ( setv ) ;setv = -INF ;}if ( addv ) {c[0]->add_val ( addv ) ;c[1]->add_val ( addv ) ;addv = 0 ;}}void link_child ( Node* o , int d ) {c[d] = o ;o->f = this ;}int is_root () {return f == null || this != f->c[0] && this != f->c[1] ;}void sign_down () {if ( !is_root () ) f->sign_down () ;push_down () ;}void rotate ( int d ) {Node* p = f ;Node* gp = f->f ;p->link_child ( c[d] , !d ) ;if ( !p->is_root () ) {if ( gp->c[0] == p ) gp->link_child ( this , 0 ) ;else gp->link_child ( this , 1 ) ;} else f = gp ;link_child ( p , d ) ;p->push_up () ;}void splay () {sign_down () ;while ( !is_root () ) {if ( f->is_root () ) {this == f->c[0] ? rotate ( 1 ) : rotate ( 0 ) ;} else {if ( f == f->f->c[0] ) {this == f->c[0] ? f->rotate ( 1 ) : rotate ( 0 ) ;rotate ( 1 ) ;} else {this == f->c[1] ? f->rotate ( 0 ) : rotate ( 1 ) ;rotate ( 0 ) ;}}}push_up () ;}void access () {Node* o = this ;Node* x = null ;while ( o != null ) {o->splay () ;o->link_child ( x , 1 ) ;o->push_up () ;x = o ;o = o->f ;}splay () ;}void make_root () {access () ;reverse () ;}Node* find_root () {access () ;Node* o = this ;while ( o->c[0] != null ) {o->push_down () ;o = o->c[0] ;}return o ;}void cut () {access () ;c[0]->f = null ;c[0] = null ;push_up () ;}void cut ( Node* o ) {//if ( o == this || find_root () != o->find_root () ) return ;o->make_root () ;cut () ;}void link ( Node* o ) {//if ( o == this || find_root () == o->find_root () ) return ;o->make_root () ;o->f = this ;}void add ( Node* o , int val ) {//if ( find_root () != o->find_root () ) return ;o->make_root () ;access () ;add_val ( val ) ;}void set ( Node* o , int val ) {//if ( find_root () != o->find_root () ) return ;o->make_root () ;access () ;set_val ( val ) ;}void query ( Node* o ) {//if ( find_root () != o->find_root () ) return ;o->make_root () ;access () ;if ( !smax_num ) printf ( "ALL SAME\n" ) ;else printf ( "%d %d\n" , smax , smax_num ) ;//printf ( "%d %d %d %d\n" , mmax , mmax_num , smax , smax_num ) ;}} ;Node memory_pool[MAXN] ;Node* cur ;Node* node[MAXN] ;int n , q ;void clear () {cur = memory_pool ;cur->newnode ( -INF ) ;null = cur ++ ;null->size = 0 ;}void solve () {int op , x , y , a , b , val ;clear () ;scanf ( "%d%d" , &n , &q ) ;For ( i , 1 , n ) {scanf ( "%d" , &val ) ;cur->newnode ( val ) ;node[i] = cur ++ ;}rep ( i , 1 , n ) {scanf ( "%d%d" , &x , &y ) ;node[x]->link ( node[y] ) ;}rep ( i , 0 , q ) {scanf ( "%d%d%d" , &op , &x , &y ) ;switch ( op ) {case 1 :scanf ( "%d%d" , &a , &b ) ;node[x]->cut ( node[y] ) ;node[a]->link ( node[b] ) ;break ;case 2 :scanf ( "%d" , &val ) ;node[x]->set ( node[y] , val ) ;break ;case 3 :scanf ( "%d" , &val ) ;node[x]->add ( node[y] , val ) ;break ;case 4 :node[x]->query ( node[y] ) ;break ;default : break ;}}}int main () {int T , cas = 0 ;scanf ( "%d" , &T ) ;while ( T -- ) {printf ( "Case #%d:\n" , ++ cas ) ;solve () ;}return 0 ;}


0 0
原创粉丝点击