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

传送门:【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 , r

const 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 ;
}


你可能感兴趣的:(bzoj)