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

hdu 1754 I Hate It

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

数组版:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define ls son[0][rt]
#define rs son[1][rt]
using namespace std;

const int maxn = 222222 ;
int son[2][maxn] , fa[maxn] , size[maxn] ;
int val[maxn] , mx[maxn] , num[maxn] ;

void push_up ( int rt ) {
	size[rt] = size[ls] + size[rs] ;
	mx[rt] = max ( val[rt] , max ( mx[ls] , mx[rs] ) ) ;
}

void new_node ( int rt ) {
	val[rt] = num[rt-1] ;
	size[rt] = 1 ;
	ls = rs = fa[rt] = 0 ;
}

int build ( int l , int r ) {
	if ( l > r ) return 0 ;
	int rt = ( l + r ) >> 1 ;
	new_node ( rt ) ;
	ls = build ( l , rt - 1 ) ; fa[ls] = rt ;
	rs = build ( rt + 1 , r ) ; fa[rs] = rt ;
	push_up ( rt ) ;
	return rt ;
}

void rot ( int rt ) {
	int y = fa[rt] , z = fa[y] , c = rt == son[0][y] ;
	son[!c][y] = son[c][rt] , fa[son[c][rt]] = y ;
	son[c][rt] = y , fa[y] = rt ;
	fa[rt] = z ;
	son[y==son[1][z]][z] = rt ;
	push_up ( y ) ;
}

void splay ( int rt , int to ) {
	while ( fa[rt] != to ) {
		int y = fa[rt] , z = fa[y] ;
		if ( z != to ) rot ( (rt==son[0][y]) ^ (y==son[0][z]) ? rt : y ) ;
		rot ( rt ) ;
	}
	push_up ( rt ) ;
}

int main() {
	int i , j , k , n , m ;
	while ( scanf ( "%d%d" , &n , &m ) != EOF ) {
		for ( i = 1 ; i <= n ; i ++ ) scanf ( "%d" , &num[i] ) ;
		num[0] = num[n+1] = -111111111 ;
		build ( 1 , n + 2 ) ;
		while ( m -- ) {
			char op[11] ;
			scanf ( "%s%d%d" , op , &j , &k ) ;
			if ( op[0] == 'Q' ) {
				k += 2 ;
				splay ( j , 0 ) ; splay ( k , j ) ;
				printf ( "%d\n" , mx[son[0][k]] ) ;
			}
			else {
				j ++ ;
				splay ( j , 0 ) ;
				val[j] = k ;
				push_up ( j ) ;
			}
		}
	}
	return 0;
}

指针版:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define Ls(rt) rt->son[0]
#define Rs(rt) rt->son[1]
#define Fa(rt) rt->fa
#define Val(rt) rt->val
#define Size(rt) rt->size
using namespace std ;

const int maxn = 222222 ;
struct Node {
	Node *son[2] , *fa ;
	int val , size , mx ;
} p[maxn] ;
Node* null = &p[0] ;
int tot ;

int num[maxn] ;

void push_up ( Node *rt ) {
	Size(rt) = Size(Ls(rt)) + Size(Rs(rt)) + 1 ;
	rt->mx = max ( Val(rt) , max ( Ls(rt)->mx , Rs(rt)->mx ) ) ;
}

Node* new_node ( int _val ) {
	Node *rt = &p[++tot] ;
	Val(rt) = _val ;
	Size(rt) = 1 ;
	Fa(rt) = Ls(rt) = Rs(rt) = null ;
	return rt ;
}

Node* build ( int l , int r ) {
	if ( l > r ) return null ;
	int mid = ( l + r ) >> 1 ;
	Node* rt = new_node ( num[mid-1] ) ;
	Ls(rt) = build ( l , mid - 1 ) ; Fa(Ls(rt)) = rt ;
	Rs(rt) = build ( mid + 1 , r ) ; Fa(Rs(rt)) = rt ;
	push_up ( rt ) ;
	return rt ;
}

void rot ( Node* rt ) {
	Node* y = Fa(rt) ,* z = Fa(y) ;
	int c = rt == Ls(y) ;
	y->son[!c] = rt->son[c] ; Fa(rt->son[c]) = y ;
	rt->son[c] = y ; Fa(y) = rt ;
	Fa(rt) = z ;
	z->son[y==z->son[1]] = rt ;
	push_up ( y ) ;
}

void splay ( Node *rt , Node *to ) {
	while ( Fa(rt) != to ) {
		Node* y = Fa(rt) ,* z = Fa(y) ;
		if ( z != to ) rot ( (rt==Ls(y)) ^ (y==Ls(z)) ? rt : y ) ;
		rot (rt) ;
	}
	push_up ( rt ) ;
}

Node* cnt ( Node* rt , int k ) {
	if ( Size(Ls(rt)) + 1 == k ) return rt ;
	if ( Size(Ls(rt)) >= k ) return cnt ( Ls(rt) , k ) ;
	return cnt ( Rs(rt) , k - Size(Ls(rt)) - 1 ) ;
}

int main () {
	int n , m , i , j , k ;
	Node* L ; Node* R ;
	while ( scanf ( "%d%d" , &n , &m ) != EOF ) {
		for ( i = 1 ; i <= n ; i ++ ) scanf ( "%d" , &num[i] ) ;
		tot = 0 ;
		num[0] = num[n+1] = 0 ;
		Node* rt = build ( 1 , n + 2 ) ;
		while ( m -- ) {
			char op[11] ;
			scanf ( "%s%d%d" , op , &j , &k ) ;
			if ( op[0] == 'Q' ) {
				j , k += 2 ;
				L = cnt ( rt , j ) ; R = cnt ( rt , k ) ;
				splay ( L , null ) ; splay ( R , L ) ;
				printf ( "%d\n" , Ls(R)->mx ) ;
				rt = L ;
			}
			else {
				j ++ ;
				L = cnt ( rt , j ) ;
				splay ( L , null ) ;
				rt = L ;
				Val(rt) = k ;
				push_up ( rt ) ;
			}
		}
	}
}



  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值