真的有人会跳表吗……
//
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e5+10,L=15;
const double P=0.25;
struct skiplist{
int x,ne,l;
}sk[N*L];int skq[N],skp;
int n;
inline void read(int& o)
{
o=0;char c=0;bool g=false;
while (c<'0' or c>'9')
g=(c=='-'),c=getchar();
while (c>='0' and c<='9')
o=o*10+c-'0',c=getchar();
o=(!g)?o:-o;
}
inline void build(int dx)
{
for (int i=1;i<=L;i++)
sk[++skp]={dx,0,0};
}
inline int randomlevel()
{
int res=1;
while (P*RAND_MAX>rand())
res++;
return res;
}
inline void view(int dx,int s)//加入值为 dx 的节点,深度为 s ;
{
for (int i=1;i<=L;i++)
skq[i]=0;
int dw=1,ds=L;
while (ds)
{
if (sk[dw].ne and sk[sk[dw].ne].x<dx)
dw=sk[dw].ne;
else
{
if (ds<=s)
sk[++skp]={dx,sk[dw].ne,0},skq[s-ds+1]=dw,
sk[dw].l+=sk[sk[dw].ne].l+1,sk[dw].ne=skp;
dw++,ds--;
}
}
sk[skq[s]].l=1,sk[skp].l=(sk[skp].ne)?1:0;
for (int i=s;i>1;i--)//使用第 i 层的节点进行操作,维护第 i-1 层的边长 ;
{
if (sk[skp-s+i-1].ne)
for (int j=skp-s+i;j!=sk[skp-s+i-1].ne+1;j=sk[j].ne)
sk[skp-s+i-1].l+=sk[j].l;
else
break;
sk[skq[i-1]].l-=sk[skp-s+i-1].l;
}
}
inline void debug(int dx)//删除一个值为 dx 的节点 ;
{
int dw=1,ds=L;
while (ds)
{
if (sk[dw].ne and sk[sk[dw].ne].x<dx)
dw=sk[dw].ne;
else
{
if (sk[sk[dw].ne].x==dx)
sk[dw].l+=max(0,sk[sk[dw].ne].l-1),sk[dw].ne=sk[sk[dw].ne].ne;
dw++,ds--;
}
}
}
inline int kth(int dx)//求第一个值为 dx 的节点排名 ;
{
int dw=1,ds=L,res=0;
while (ds)
{
if (sk[dw].ne and sk[sk[dw].ne].x<dx)
res+=sk[dw].l,dw=sk[dw].ne;
else
dw++,ds--;
}
return res+1;
}
inline int defind(int k)//求第 k 小的节点值 ;
{
int dw=1,ds=L;
while (ds)
{
if (sk[dw].ne and sk[dw].l<=k)
k-=sk[dw].l,dw=sk[dw].ne;
else
dw++,ds--;
}
return sk[dw-1].x;
}
inline int lower(int dx)//求值为 dx 的节点其前驱 ;
{
int dw=1,ds=L;
while (ds)
{
if (sk[dw].ne and sk[sk[dw].ne].x<dx)
dw=sk[dw].ne;
else
dw++,ds--;
}
return sk[dw-1].x;
}
inline int upper(int dx)//求值为 dx 的节点其后继 ;
{
int dw=1,ds=L;
while (ds)
{
if (sk[dw].ne and sk[sk[dw].ne].x<=dx)
dw=sk[dw].ne;
else
dw++,ds--;
}
return sk[sk[dw-1].ne].x;
}
int main ()
{
// freopen("skiplist.in","r",stdin);
// freopen("skiplist.out","w",stdout);
srand(time(0)),build(-INT_MAX);
int op,x;
read(n);
while (n-->0)
{
read(op),read(x);
switch (op)
{
case 1:
view(x,randomlevel());
break;
case 2:
debug(x);
break;
case 3:
printf ("%d\n",kth(x));
break;
case 4:
printf ("%d\n",defind(x));
break;
case 5:
printf ("%d\n",lower(x));
break;
default:
printf ("%d\n",upper(x));
}
}
return 0;
}
/*
12
1 -2
1 2
1 3
1 0
1 2
1 1
5 1
2 0
5 1
2 2
4 4
6 1
0
-2
3
2
*/