#include <cstdio>
#include <algorithm>
#include <time.h>
#include <cstdlib>
#include <iostream>
using namespace std;
const int MAXN=1e6+50;
int n;
int tot;//树的大小
int lin,rt;
int l[MAXN<<2],r[MAXN<<2];
int val[MAXN<<2],cnt[MAXN<<2],size[MAXN<<2],key[MAXN<<2];
//更新以id位根节点的子树大小
void push_up(int id)
{
size[id]=size[l[id]]+size[r[id]]+cnt[id];
}
//左旋操作
void left_rorate(int &u)//&u就是把u的地址取出来
{
int t=r[u];
r[u]=l[t];
l[t]=u;
size[t]=size[u];
push_up(u);
u=t;
}
//右旋操作
void right_rorate(int &u)
{
int t=l[u];
l[u]=r[t];
r[t]=u;
size[t]=size[u];
push_up(u);
u=t;
}
//在以u为根节点的子树中插入v
void insert(int &u,int v)
{
if(!u)
return (void)(size[u=++tot]=1,val[u]=v,cnt[u]=1,key[u]=rand());
size[u]++;
if(val[u]==v)
return (void)(cnt[u]++);
else if(val[u]<v)
{
insert(r[u],v);
if(key[u]>key[r[u]])
left_rorate(u);
}
else if(val[u]>v)
{
insert(l[u],v);
if(key[u]>key[l[u]])
right_rorate(u);
}
push_up(u);
}
//在以u为根节点的子树中删除v
bool Delete(int &u,int v)
{
if(!u)
return false;
if(val[u]==v)
{
if(cnt[u]>1)
{
cnt[u]--,size[u]--;
return true;
}
else if(!l[u] or !r[u])
{
u=l[u]+r[u];
return true;
}
else if(key[l[u]]<key[r[u]])
{
right_rorate(u);
return Delete(u,v);
}
else
{
left_rorate(u);
return Delete(u,v);
}
}
else if(val[u]<v)
{
bool flag=Delete(r[u],v);
if(flag)
size[u]--;
return flag;
}
else if(val[u]>v)
{
bool flag=Delete(l[u],v);
if(flag)
size[u]--;
return flag;
}
push_up(u);
}
//查询v的排名
int ask_rank(int u,int v)
{
if(!u)
return 1;
if(val[u]==v)
return size[l[u]]+1;
else if(val[u]<v)
return size[l[u]]+cnt[u]+ask_rank(r[u],v);
else if(val[u]>v)
return ask_rank(l[u],v);
}
//查询排名为v的数
int find_rank(int u,int v)
{
if(!u)
return 0;
if(size[l[u]]+1==v)
return val[u];
else if(size[l[u]]>=v)
return find_rank(l[u],v);
else if(size[l[u]]+cnt[u]<v)
return find_rank(r[u],v-size[l[u]]-cnt[u]);
}
void ask_pre(int u,int x)
{
if(!u)
return;
if(val[u]<x)
lin=u,ask_pre(r[u],x);
else
ask_pre(l[u],x);
}
void ask_net(int u,int x)
{
if(!u)
return;
if(val[u]>x)
lin=u,ask_net(l[u],x);
else
ask_net(r[u],x);
}
int pre(int x)
{
ask_pre(rt,x);
return val[lin];
}
int net(int x)
{
ask_net(rt,x);
return val[lin];
}
int main()
{
// srand(time(NULL));
scanf("%d",&n);
// int hhd=1;
for(int i=1,c,x;i<=n;i++)
{
scanf("%d%d",&c,&x);
switch(c)
{
case 1:
insert(rt,x);break;
case 2:
Delete(rt,x);break;
case 3:
printf("%d\n",ask_rank(rt,x));break;
case 4:
printf("%d\n",find_rank(rt,x));break;
case 5:
printf("%d\n",pre(x));break;
case 6:
printf("%d\n",net(x));break;
default:
break;
}
}
}
每次输出的错误答案都不一样,