更新當前節點的狀況
void update(int rt){
t[rt].sz = t[rt].cnt + t[t[rt].ch[0]].sz + t[t[rt].ch[1]].sz;
}
判斷自己是父親的左右兒子
void get(int rt){
return (t[rt].f == t[t[rt].f].ch[1]);
}
喜聞樂見的旋轉操作(把他分爲三個部分就好記憶一點分別是爺爺,爸爸,兒子(三代同堂))
int rote(int rt){
int d = get(rt);
int ff = t[rt].f;
if(ff == 0)return 0;
int gg = t[ff].f;
int cc = t[rt].ch[d ^ 1];
if(gg)t[gg].ch[get(ff)] = rt;
t[rt].f = gg;
t[rt].ch[d ^ 1] = ff;
if(ff)t[ff].f = rt;
t[ff].ch[d] = cc;
if(cc)t[cc].f = ff;
update(ff);
update(rt);
}
splay到根
int splay(int rt){
int d;
for(int f = t[rt].f ; (f = t[rt].f) ; rote(rt)){
if(get(f) == get(rt))rote(f);
else rote(rt);
}
op = rt;
}
插入。。。
int add(int rt , int dx){
if(!rt){
rt = ++tot;
op = rt;
t[rt].sz = t[rt].cnt = 1;
t[rt].val = dx;
t[rt].f = 0;
return 0;
}
int d;
while(1){
if(t[rt].val == dx){
t[rt].cnt++;
splay(rt);
return 0;
}
d = (t[rt].val < dx);
if(!t[rt].ch[d]){
t[rt].ch[d] = ++tot;
t[tot].cnt = t[tot].sz = 1;
t[tot].val = dx;
t[tot].f = rt;
splay(tot);
return 0;
}
rt = t[rt].ch[d];
}
}
刪除
int del(int dx){
rank(op , dx);
if(t[op].cnt > 1){
t[op].cnt--;
return 0;
}
if(!t[op].ch[0] && !t[op].ch[1]){
op = 0;
return 0;
}
if(!t[op].ch[0]){
t[t[op].ch[1]].f = 0;
op = t[op].ch[1];
return 0;
}
if(!t[op].ch[1]){
t[t[op].ch[0]].f = 0;
op = t[op].ch[0];
return 0;
}
splay(nxt(op));
t[op].ch[1] = t[t[op].ch[1]].ch[1];
t[t[op].ch[1]].f = op;
up(op);
}
注意別寫錯就好了。。。。。記得後面是吧前驅splay上來,然後刪除就好了。。。
其他的沒什麼好強調的了
#include<bits/stdc++.h>
#define MAXN 200005
using namespace std;
struct Splay{
int tot,op;
struct node{
int ch[2],f,sz,cnt,val;
}t[MAXN];
void init(){//³õʼ»¯
tot = op = 0;
}
int get(int rt){
return (t[t[rt].f].ch[1] == rt);
}
int up(int rt){
t[rt].sz = t[rt].cnt + t[t[rt].ch[0]].sz + t[t[rt].ch[1]].sz;
}
int rote(int rt){
int d = get(rt);
int ff = t[rt].f;
if(ff == 0)return 0;
int gg = t[ff].f;
int cc = t[rt].ch[d ^ 1];
if(gg)t[gg].ch[get(ff)] = rt;
t[rt].f = gg;
t[rt].ch[d ^ 1] = ff;
if(ff)t[ff].f = rt;
t[ff].ch[d] = cc;
if(cc)t[cc].f = ff;
up(ff);
up(rt);
}
int splay(int rt){
int d;
for(int f = t[rt].f ; (f = t[rt].f) ; rote(rt)){
if(get(f) == get(rt))rote(f);
else rote(rt);
}
op = rt;
}
int add(int rt , int dx){
if(!rt){
rt = ++tot;
op = rt;
t[rt].sz = t[rt].cnt = 1;
t[rt].val = dx;
t[rt].f = 0;
return 0;
}
int d;
while(1){
if(t[rt].val == dx){
t[rt].cnt++;
splay(rt);
return 0;
}
d = (t[rt].val < dx);
if(!t[rt].ch[d]){
t[rt].ch[d] = ++tot;
t[tot].cnt = t[tot].sz = 1;
t[tot].val = dx;
t[tot].f = rt;
splay(tot);
return 0;
}
rt = t[rt].ch[d];
}
}
int kth(int rt , int dx){
int d;
while(1){
if(t[t[rt].ch[0]].sz >= dx)rt = t[rt].ch[0];
else{
dx -= t[t[rt].ch[0]].sz;
if(t[rt].cnt >= dx){
return t[rt].val;
}
else dx -= t[rt].cnt , rt = t[rt].ch[1];
}
}
}
int rank(int rt , int dx){
int d;
while(1){
if(t[rt].val > dx)rt = t[rt].ch[0];
else if(t[rt].val < dx)rt = t[rt].ch[1];
else{
splay(rt);return t[t[rt].ch[0]].sz;
}
}
}
int pre(int x){
x = t[x].ch[1];
while(t[x].ch[0])x = t[x].ch[0];
return x;
}
int nxt(int x){
x = t[x].ch[0];
while(t[x].ch[1])x = t[x].ch[1];
return x;
}
int del(int dx){
rank(op , dx);
if(t[op].cnt > 1){
t[op].cnt--;
return 0;
}
if(!t[op].ch[0] && !t[op].ch[1]){
op = 0;
return 0;
}
if(!t[op].ch[0]){
t[t[op].ch[1]].f = 0;
op = t[op].ch[1];
return 0;
}
if(!t[op].ch[1]){
t[t[op].ch[0]].f = 0;
op = t[op].ch[0];
return 0;
}
splay(nxt(op));
t[op].ch[1] = t[t[op].ch[1]].ch[1];
t[t[op].ch[1]].f = op;
up(op);
}
}T;
int main(){
T.init();
int u;cin>>u;
for(int i = 1 ; i <= u ; i++){
int x,y;cin>>x>>y;
if(x == 1)T.add(T.op , y);
if(x == 2)T.del(y);
if(x == 3)cout<<T.rank(T.op , y) + 1<<endl;
if(x == 4)cout<<T.kth(T.op , y)<<endl;
if(x == 5){
T.add(T.op , y);
cout<<T.t[T.nxt(T.op)].val<<endl;
T.del(y);
}
if(x == 6){
T.add(T.op , y);
cout<<T.t[T.pre(T.op)].val<<endl;
T.del(y);
}
}
}