#include<bits/stdc++.h>
using namespace std;
const int N=110000;
int n,root,tot;
struct FHQ_treap
{
int key,val,siz,lson,rson;
}tree[N];
void add(int x)
{
tree[++tot].val=x;
tree[tot].key=rand();
tree[tot].rson=tree[tot].lson=0;
tree[tot].siz=1;
return;
}
void update(int u)
{
tree[u].siz=tree[tree[u].lson].siz+tree[tree[u].rson].siz+1;
return;
}
void divide(int u,int x,int &l,int &r)
{
if(u==0)
{
l=r=0;
return;
}
int lson=tree[u].lson,rson=tree[u].rson;
if(tree[u].val<=x)
l=u,divide(rson,x,tree[u].rson,r);//注意这里用单个变量lson和rson代替是错误的,l与r与divide直接相关,接下来的递归中要实际改变d[u]的llson,rson值
else
r=u,divide(lson,x,l,tree[u].lson);
update(u);
}
int merge(int l,int r)
{
if(l==0)
return r;
if(r==0)
return l;
if(tree[l].key<tree[r].key)
{
tree[l].rson=merge(tree[l].rson,r);
update(l);
return l;
}
else
{
tree[r].lson=merge(l,tree[r].lson);
update(r);
return r;
}
}
int kth(int u,int k)
{
int lson=tree[u].lson,rson=tree[u].rson;
if(k<=tree[lson].siz)
return kth(lson,k);
else
{
if(tree[lson].siz+1==k)
{
return u;
}
else
{
return kth(rson,k-1-tree[lson].siz);
}
}
}
int main()
{
srand(time(NULL));
scanf("%d",&n);
int l,r,p;
for(int i=1,opt,x;i<=n;i++)
{
scanf("%d%d",&opt,&x);
switch(opt)
{
case 1:
{
divide(root,x,l,r);
add(x);
root=merge(merge(l,tot),r);
break;
}
case 2:
{
divide(root,x,l,p);
divide(l,x-1,l,r);//只删除一个
r=merge(tree[r].lson,tree[r].rson);
root=merge(merge(l,r),p);
break;
}
case 3:
{
divide(root,x-1,l,r);
printf("%d\n",tree[l].siz+1);
root=merge(l,r);
break;
}
case 4:
{
printf("%d\n",tree[kth(root,x)].val);
break;
}
case 5:
{
divide(root,x-1,l,r);
printf("%d\n",tree[kth(l,tree[l].siz)].val);
root=merge(l,r);
break;
}
case 6:
{
divide(root,x,l,r);
printf("%d\n",tree[kth(r,1)].val);
root=merge(l,r);
break;
}
default:
{
break;
}
}
// printf("%d.%d\n",i,root);//DEBUG
}
return 0;
}
/*
插入 xx 数
删除 xx 数(若有多个相同的数,因只删除一个)
查询 xx 数的排名(排名定义为比当前数小的数的个数 +1+1 )
查询排名为 xx 的数
求 xx 的前驱(前驱定义为小于 xx,且最大的数)
求 xx 的后继(后继定义为大于 xx,且最小的数)
*/
在分割查找树的函数中,传参数必须传实际的参数,不可以用及时定义的简化码量的变量,否则在随后的递归中会修改不正常。
也就我能犯这种错误吧(