hdu 1754 I Hate It (splay tree伸展树)

hdu 1754 I Hate It

其实我只是来存一下我的splay模板的。。请大牛们多多指教

 

#include<stdio.h>

#include<string.h>

#include<algorithm>

using namespace std ;



const int maxn = 222222 ;



int son[2][maxn] , col[maxn] , fa[maxn] , size[maxn] , val[maxn] ;

int tot ;

int num[maxn] ;



void new_node () {

	size[tot] = 1 ;

	fa[tot] = son[0][tot] = son[1][tot] = -1 ;

	val[tot] = col[tot] = 0 ;

	tot ++ ;

}



void update ( int rt ) {

	size[rt] = 1 ;

	col[rt] = val[rt] ;

	if ( son[0][rt] != -1 ) 

		size[rt] += size[son[0][rt]] , col[rt] = max ( col[rt] , col[son[0][rt]] ) ;

	if ( son[1][rt] != -1 )

		size[rt] += size[son[1][rt]] , col[rt] = max ( col[rt] , col[son[1][rt]] ) ;

}



int build ( int l , int r ) {

	if ( l > r ) return -1 ;

	int mid = ( l + r ) >> 1 ;

	new_node () ;

	int temp = tot - 1 ;

	val[temp] = num[mid] ;

	son[0][temp] = build ( l , mid - 1 ) ;  

	if ( son[0][temp] != -1 ) fa[son[0][temp]] = temp ;

	son[1][temp] = build ( mid + 1 , r ) ;

	if ( son[1][temp] != -1 ) fa[son[1][temp]] = temp ;

	update ( temp ) ;

	return temp ;

}



void rot ( int rt , int c ) {

	int y = fa[rt] , z = fa[y] ;

	son[!c][y] = son[c][rt] ;

	if ( son[c][rt] != -1 ) fa[son[c][rt]] = y ;

	fa[rt] = z ;

	if ( z != -1 ) {

		if ( y == son[0][z] ) son[0][z] = rt ;

		else son[1][z] = rt ;

	}

	son[c][rt] = y , fa[y] = rt ;

	update ( y ) ;

}



void splay ( int rt , int to ) {

	while ( fa[rt] != to ) {

		if ( fa[fa[rt]] == to ) {

			if ( rt == son[0][fa[rt]] ) rot ( rt , 1 ) ;

			else rot ( rt , 0 ) ;

		}

		else {

			int y = fa[rt] , z = fa[y] ;

			if ( rt == son[0][y] ) {

				if ( y == son[0][z] ) rot ( y , 1 ) , rot ( rt , 1 ) ;

				else rot ( rt , 1 ) , rot ( rt , 0 ) ;

			}

			else {

				if ( y == son[1][z] ) rot ( y , 0 ) , rot ( rt , 0 ) ;

				else rot ( rt , 0 ) , rot ( rt , 1 ) ;

			}

		}

	}

	update ( rt ) ;

	/*为什么只要在最后更新rt节点呢?因为在旋转的过程中,fa[rt]总是旋到rt下面的

	所以在旋转的时候,我们不断的更新fa[rt],而不需要一直更新rt,只要在splay之后更新rt就好了

	*/

}



int find ( int rt , int key ) {

	int cnt = 0 ;

	if ( son[0][rt] != -1 ) cnt = size[son[0][rt]] ;

	if ( cnt + 1 == key ) return rt ;

	if ( cnt >= key ) return find ( son[0][rt] , key ) ;

	return find ( son[1][rt] , key - cnt - 1 ) ;

}



int main () {

	int n , m , i , j , k , a , b ;

	char op[11] ;

	while ( scanf ( "%d%d" , &n , &m ) != EOF ) {

		for ( i = 1 ; i <= n ; i ++ ) scanf ( "%d" , &num[i] ) ;

		tot = 0 ;

		int root = build ( 0 , n + 1 ) , temp ;

		while ( m -- ) {

			scanf ( "%s%d%d" , op , &a , &b ) ;

			a ++ , b ++ ;//因为建树的时候,把0也建进去了,但实际上0是不在原数组中的,所有往后推移一位

			if ( op[0] == 'U' ) {

				temp = find ( root , a ) ;

				splay ( temp , -1 ) ;

				root = temp ;

				val[root] = b - 1 ;

			//	update ( root ) ;

			//这里为什么不用更新rt呢?因为对于size的值是不会变的,而val值已经更新了,而对于col值,下次是splay时,肯定会更新掉的

			}

			else {

				temp = find ( root , a - 1 ) ;

				splay ( temp , -1 ) ;

				root = temp ;

				temp = find ( root , b + 1 ) ;

				splay ( temp , root ) ;

				printf ( "%d\n" , col[son[0][temp]] ) ;

			}

		}

	}

}


 

 

你可能感兴趣的:(tree)