【BZOJ】2002 [Hnoi2010]Bounce 弹飞绵羊 LCT入门题

来源:互联网 发布:拉维奇 知乎 编辑:程序博客网 时间:2024/04/24 06:29

传送门:【BZOJ】2002 [Hnoi2010]Bounce 弹飞绵羊


题目分析:LCT入门题,只有cut和link操作。


代码如下:


#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std ;typedef long long LL ;#pragma comment(linker, "/STACK:16777216")#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 root 1 , 1 , cnt#define mid ( ( l + r ) >> 1 )#define rt o , l , rconst int MAXN = 200005 ;struct Node* null ;struct Node {Node* c[2] ;Node* f ;int sum ;int v ;int flip ;void newnode ( int val ) {sum = val ;v = val ;f = c[0] = c[1] = null ;}void reverse () {if ( this == null ) return ;swap ( c[0] , c[1] ) ;flip ^= 1 ;}void push_up () {sum = c[0]->sum + v + c[1]->sum ;}void push_down () {if ( flip ) {c[0]->reverse () ;c[1]->reverse () ;flip = 0 ;}}void sign_down () {if ( !is_root () ) f->sign_down () ;push_down () ;}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 rotate ( int d ) {Node* p = f ;Node* gp = f->f ;p->link_child ( c[d] , !d ) ;if ( !f->is_root () ) {if ( f == gp->c[0] ) 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 () ;}void cut () {access () ;c[0]->f = null ;c[0] = null ;push_up () ;}void cut ( Node* o ) {make_root () ;o->cut () ;}void link ( Node* o ) {make_root () ;f = o ;}int query ( Node* o ) {make_root () ;o->access () ;return o->sum - 1 ;}} ;Node pool[MAXN] ;Node* cur ;Node* node[MAXN] ;int d[MAXN] ;int n , q ;void clear () {cur = pool ;null = cur ++ ;null->newnode ( 0 ) ;}void solve () {int op , x , y ;clear () ;For ( i , 1 , n + 1 ) {node[i] = cur ++ ;node[i]->newnode ( 1 ) ;}For ( i , 1 , n ) {scanf ( "%d" , &d[i] ) ;if ( i + d[i] > n ) d[i] = n + 1 - i ;node[i]->link ( node[i + d[i]] ) ;}scanf ( "%d" , &q ) ;while ( q -- ) {scanf ( "%d" , &op ) ;if ( op == 1 ) {scanf ( "%d" , &x ) ;++ x ;printf ( "%d\n" , node[x]->query ( node[n + 1] ) ) ;} else {scanf ( "%d%d" , &x , &y ) ;++ x ;if ( x + d[x] > n && y >= d[x] ) continue ;node[x]->cut ( node[x + d[x]] ) ;d[x] = y ;if ( x + d[x] > n ) d[x] = n + 1 - x ;node[x]->link ( node[x + d[x]] ) ;}}}int main () {while ( ~scanf ( "%d" , &n ) ) solve () ;return 0 ;}


0 0
原创粉丝点击