代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1e5+5;
struct node {
int l , r , val ;
int size ;
int high ;
}avl[N] ;
int cnt , root , n ;
inline void newnode(int &now , int val) {
avl[now==++cnt].val = val ;
avl[cnt].size = 1 ;
avl[cnt].high = 1 ;
}
inline void update(int now) {
avl[now].size=avl[avl[now].l].size
+avl[avl[now].r].size+1;
avl[now].high = max(avl[avl[now].l].high
,avl[avl[now].r].high)+1;
}//更新
inline int factor ( int now ) {
return avl[avl[now].l].high
-avl[avl[now].r].high ;
}//求平衡因子:左子树高度-右子树高度
inline void left(int &now)//左旋拎右左挂右
{
/*左旋->将右子树作为新根,根作为其左子树
原右子树的左子树挂到原根的右边*/
int r = avl[now].r ;//右子树
avl[now].r = avl[r].l ;//左挂右
avl[r].l = now ;
now = r ;//拎右
update(avl[now].l);
update(now);
}
inline void right(int &now) {//右旋拎左右挂左
/*右旋->将左子树作为新根,原根作为其右子树
原左子树的右子树挂到原根的左边*/
int l= avl[now].l ;//左子树
avl[now].l = avl[l].r ;//右挂左
avl[l].r = now ;
now = l ;//拎左
update(avl[now].r);
update(now);
}
inline void check(int &now) {//检查是否平衡
int now_factor = factor(now) ;
if(now_factor>1)//左子树太高
{
int left_factor = factor(avl[now].l) ;
if(left_factor>0) right(now) ;//LL
else left(avl[now].l),right(now) ;//LR
}
else if(now_factor< -1) {
int right_factor = factor(avl[now].r) ;
if(right_factor<0) left(now) ;//RR
else right(avl[now].r),left(now) ;//RL
}
else if(now)update(now) ;
//如果平衡且非空,直接更新
}
void ins(int &now,int val) {
if(!now)newnode(now,val) ;
else if(val<avl[now].val)
ins(avl[now].l,val) ;
else ins(avl[now].r,val) ;
update(now) ;
check(now) ;
}
int find_nxt ( int &now , int fa )
{
int res ;
if(!avl[now].l) { //找到了后继
res = now ; //确定返回值
avl[fa].l = avl[now].r ;
//父亲的左儿改为该点的右儿
update(now) ;
update(fa) ;
}
else { //没找到
res = find_nxt(avl[now].l,now) ;//接着找
check(now) ;//检查
}
return res ;//返回结点编号
}//找某个点的后继
void del ( int &now , int val ) {
if(val==avl[now].val) { //要删除的结点
int l = avl[now].l ;
int r = avl[now].r ;
if(!l||!r) now = l + r ;
//如果无儿或单儿,当前根节点替换
else {//双儿
now = find_nxt(r,r) ; //找后继,替换当前
if(now!=r) { //如果后继不是原来的右儿
avl[now].r = r ; //右儿改为原来的右儿
}
avl[now].l = l ; //连接左儿
}
}
else if(val<avl[now].val)
del(avl[now].l,val) ;
else del(avl[now].r,val) ;
update(now) ;
check(now) ; //递归回溯检查
}
int getrank ( int val ) {
int now = root , rank = 1 ;
while(now) {
if(val<=avl[now].val) {
now = avl[now].l ;
}
else {
rank += avl[avl[now].l].size + 1 ;
now = avl[now].r ;
}
}
return rank ;
}
int getnum(int rank) {
int now = root ;
while(now) {
if(avl[avl[now].l].size+1==rank)
break ;
else if(avl[avl[now].l].size>=rank) {
now = avl[now].l ;
}
else {
rank -= avl[avl[now].l].size + 1 ;
now = avl[now].r ;
}
}
return avl[now].val ;
}
int main ( ) {
cin >> n ;
while(n--) {
int opt , x ;
cin >> opt >> x ;
switch(opt) {
case 1 :
ins(root,x) ;
break ;
case 2 :
del(root,x) ;
break ;
case 3 :
cout << getrank ( x ) << endl ;
break ;
case 4 :
cout << getnum (x) << endl ;
break ;
case 5 :
cout << getnum(getrank(x)-1) << endl ;
break ;
case 6 :
cout << getnum(getrank(x+1)) << endl ;
break ;
}
}
system("pause") ;
return 0 ;
}