#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
const int MAXN=500005;
const int inf=0x3f3f3f3f;
using namespace std;
struct node{
int lc,rc,h,data,num;
}tree[MAXN+5];
int cnt,root;
inline void Read(int &Ret){
char ch;bool flag=0;
for(;ch=getchar(),ch<'0'||ch>'9';)if(ch=='-')flag=1;
for(Ret=ch-'0';ch=getchar(),'0'<=ch&&ch<='9';Ret=Ret*10+ch-'0');
flag&&(Ret=-Ret);
}
inline void update(int i){
tree[i].h=max(tree[tree[i].lc].h,tree[tree[i].rc].h)+1;
tree[i].num=tree[tree[i].lc].num+tree[tree[i].rc].num+1;
}
int zig(int i){
int t=tree[i].lc;
tree[i].lc=tree[t].rc;
tree[t].rc=i;
update(i); update(t);
return t;
}
int zag(int i){
int t=tree[i].rc;
tree[i].rc=tree[t].lc;
tree[t].lc=i;
update(i); update(t);
return t;
}
int zigzag(int i){
tree[i].rc=zig(tree[i].rc);
return zag(i);
}
int zagzig(int i){
tree[i].lc=zag(tree[i].lc);
return zig(i);
}
void maintain(int &i){
if(tree[tree[i].lc].h==tree[tree[i].rc].h+2)
{
int t=tree[i].lc;
if(tree[tree[t].rc].h==tree[tree[i].rc].h+1) i=zagzig(i);
else if(tree[tree[t].lc].h==tree[tree[i].rc].h+1) i=zig(i);
}
else if(tree[tree[i].rc].h==tree[tree[i].lc].h+2)
{
int t=tree[i].rc;
if(tree[tree[t].lc].h==tree[tree[i].lc].h+1) i=zigzag(i);
else if(tree[tree[t].rc].h==tree[tree[i].lc].h+1) i=zag(i);
}
update(i);
}
void Insert(int &i,int x){
if(!i)
{
tree[++cnt].data=x;
tree[cnt].h=tree[cnt].num=1;
i=cnt; return;
}
if(x<=tree[i].data) Insert(tree[i].lc,x);
else Insert(tree[i].rc,x);
maintain(i); return;
}
int Delete(int &i,int x){
int res;
if(tree[i].data==x||(x>tree[i].data&&!tree[i].rc)||(x<tree[i].data&&!tree[i].lc))
{
res=tree[i].data;
if(!tree[i].rc||!tree[i].lc)
{i=tree[i].rc+tree[i].lc;return res;}
else tree[i].data=Delete(tree[i].lc,x);
}
else
{
if(x<tree[i].data) res=Delete(tree[i].lc,x);
else res=Delete(tree[i].rc,x);
}
maintain(i); return res;
}
int getdata(int i,int x){
if(!i) return 0;
if(tree[tree[i].lc].num+1==x)
return tree[i].data;
else if(tree[tree[i].lc].num+1>x) return getdata(tree[i].lc,x);
else return getdata(tree[i].rc,x-tree[tree[i].lc].num-1);
}
int getrank(int i,int x){
if(!i) return 1;
if(x<=tree[i].data) return getrank(tree[i].lc,x);
else return tree[tree[i].lc].num+1+getrank(tree[i].rc,x);
}
int lower(int x){
int i=root,res=-inf;
while(i)
{
if(tree[i].data==x) i=tree[i].lc;
else if(tree[i].data<x)
res=max(res,tree[i].data),i=tree[i].rc;
else i=tree[i].lc;
}
return res;
}
int upper(int x){
int i=root,res=inf;
while(i)
{
if(tree[i].data==x) i=tree[i].rc;
else if(tree[i].data>x)
res=min(res,tree[i].data),i=tree[i].lc;
else i=tree[i].rc;
}
return res;
}
int main()
{
int n,opt,x; Read(n);
for(int i=1;i<=n;i++)
{
Read(opt); Read(x);
switch(opt)
{
case 1: Insert(root,x); break;
case 2: Delete(root,x); break;
case 3: printf("%d\n",getrank(root,x)); break;
case 4: printf("%d\n",getdata(root,x)); break;
case 5: printf("%d\n",lower(x)); break;
case 6: printf("%d\n",upper(x)); break;
}
}
return 0;
}
第一行为n,表示操作的个数(n <= 500000)
下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6, -10^7 <= x <= 10^7)
大规模输入数据,建立读入优化
输出
对于操作3,4,5,6每行输出一个数,表示对应答案