裸的平衡树
写的是treap
#include<bits/stdc++.h>
using namespace std;
int n , root , tot;
const int INF = 0x7fffffff;
struct tree{
int val , dat;
int cnt , size;
int l , r;
}a[101000];
int read()
{
int sum = 0;char c = getchar();bool flag = true;
while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
if(flag) return sum;
else return -sum;
}
int New(int v)
{
a[++tot].val = v;
a[tot].dat = rand();
a[tot].cnt = a[tot].size = 1;
return tot;
}
void update(int x)
{
a[x].size = a[a[x].l].size + a[a[x].r].size + a[x].cnt;
return;
}
void build()
{
New(-INF);New(INF);
a[1].r = 2;root = 1;
update(root);
return;
}
void zig(int &p)//右旋
{
int q = a[p].l;
a[p].l = a[q].r;a[q].r = p;p = q;
update(a[p].r);update(p);
return;
}
void zag(int &p)//左旋
{
int q = a[p].r;
a[p].r = a[q].l;a[q].l = p;p = q;
update(a[p].l);update(p);
return;
}
void insert(int &x,int v)
{
if(x == 0)
{
x = New(v);
return;
}
if(v == a[x].val)
{
a[x].cnt++;
a[x].size++;
return;
}
else
if(v > a[x].val)
{
insert(a[x].r , v);
if(a[a[x].r].dat > a[x].dat) zag(x);//左旋
}
else
if(v < a[x].val)
{
insert(a[x].l , v);
if(a[a[x].l].dat > a[x].dat) zig(x);//右旋
}
update(x);
return;
}
void dele(int &x,int v)
{
if(x == 0) return;
if(v == a[x].val)
{
if(a[x].cnt > 1)
{
a[x].cnt--;a[x].size--;
return;
}
if(a[x].l || a[x].r)
{
if(a[x].r == 0|| a[a[x].l].dat > a[a[x].r].dat)
zig(x) , dele(a[x].r , v);
else
zag(x) , dele(a[x].l , v);
update(x);
}
else x = 0;
return;
}
v < a[x].val ? dele(a[x].l , v) : dele(a[x].r , v);
update(x);
return;
}
int find_rank(int x,int v)
{
if(v == a[x].val) return a[a[x].l].size + 1;
return v < a[x].val ? find_rank(a[x].l , v)
: find_rank(a[x].r , v) + a[a[x].l].size + a[x].cnt;
}
int find_num(int x,int rank)
{
if(a[a[x].l].size >= rank) return find_num(a[x].l , rank);
if(a[a[x].l].size + a[x].cnt >= rank) return a[x].val;
return find_num(a[x].r , rank - a[a[x].l].size - a[x].cnt);
}
int find_pre( int x , int v )
{
int ans = 1;
while(x)
{
if(a[x].val == v)
{
if(a[x].l > 0)
{
x = a[x].l;
while(a[x].r > 0) x = a[x].r;
ans = x;
}
break;
}
if(a[x].val < v && a[x].val > a[ans].val) ans = x;
x = v < a[x].val ? a[x].l : a[x].r;
}
return a[ans].val;
}
int find_next( int x , int v )
{
int ans = 2;
while(x)
{
if(v == a[x].val)
{
if(a[x].r > 0)
{
x = a[x].r;
while(a[x].l > 0) x = a[x].l;
ans = x;
}
break;
}
if(a[x].val > v && a[x].val < a[ans].val) ans = x;
x = v < a[x].val ? a[x].l : a[x].r;
}
return a[ans].val;
}
int main()
{
build();
n = read();
for(int i = 1;i <= n;++i)
{
int k = read() , x = read();
if(k == 1) insert(root , x);
if(k == 2) dele(root , x);
if(k == 3) printf("%d\n",find_rank(root , x) - 1);
if(k == 4) printf("%d\n",find_num(root , x + 1));
if(k == 5) printf("%d\n",find_pre(root , x));
if(k == 6) printf("%d\n",find_next(root , x));
}
return 0;
}