rt 已经知道是左旋右旋的问题,但不知道怎么调
#include<bits/stdc++.h>
using namespace std;
struct node
{
int size;
int rs;
int ls;
int v;
int p;
};
node tree[100010];
int tot,root;
void zs(int pos)
{
tree[pos].size=tree[tree[pos].ls].size+tree[tree[pos].rs].size+1;
return;
}
void lturn(int &pos)
{
node x=tree[tree[pos].rs];
tree[pos].rs=x.ls;
x.ls=pos;
x.size=tree[pos].size;
zs(pos);
tree[pos]=x;
return;
}
void rturn(int &pos)
{
node x=tree[tree[pos].ls];
tree[pos].ls=x.rs;
x.rs=pos;
x.size=tree[pos].size;
zs(pos);
tree[pos]=x;
return;
}
void insert(int &pos,int x)
{
if(!pos)
{
pos=++tot;
tree[pos].v=x;
tree[pos].p=rand();
tree[pos].size=1;
return;
}
if(x<tree[pos].v)
{
insert(tree[pos].ls,x);
if(tree[pos].p<tree[tree[pos].ls].p)
rturn(pos);
}
else
{
insert(tree[pos].rs,x);
if(tree[pos].p<tree[tree[pos].rs].p)
lturn(pos);
}
zs(pos);
return ;
}
void remove(int pos,int x)
{
if(!pos)
return;
if(tree[pos].v==x)
{
if(tree[pos].ls|tree[pos].rs)
{
if(tree[tree[pos].ls].p>tree[tree[pos].rs].p)
{
rturn(pos);
remove(tree[pos].rs,x);
}
else
{
lturn(pos);
remove(tree[pos].ls,x);
}
}
else
pos=0;
}
else
{
if(x<tree[pos].v)
remove(tree[pos].ls,x);
else
remove(tree[pos].rs,x);
}
if(pos)
zs(pos);
}
int ranknum(int pos,int x)
{
if(!pos)
return 1;
if(x<tree[pos].v)
return ranknum(tree[pos].ls,x);
else
return ranknum(tree[pos].rs,x)+tree[tree[pos].ls].size+1;
}
int numrank(int pos,int x)
{
int k=tree[tree[pos].ls].size;
if(x==k+1)
return tree[pos].v;
else if(x<=k)
return numrank(tree[pos].ls,x);
else
return numrank(tree[pos].rs,x-k-1);
}
int prev(int pos,int x)
{
if(!pos)
return -1000000000;
if(x<tree[pos].v)
return prev(tree[pos].ls,x);
else
return max(tree[pos].v,prev(tree[pos].rs,x));
}
int nxt(int pos,int x)
{
if(!pos)
return 1000000000;
if(x>=tree[pos].v)
return nxt(tree[pos].rs,x);
else
return min(tree[pos].v,nxt(tree[pos].ls,x));
}
int main()
{
int n,ox,op;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&op,&ox);
if(op==1)
insert(root,ox);
if(op==2)
remove(root,ox);
if(op==3)
printf("%d\n",ranknum(root,ox));
if(op==4)
printf("%d\n",numrank(root,ox));
if(op==5)
printf("%d\n",prev(root,ox));
if(op==6)
printf("%d\n",nxt(root,ox));
}
return 0;
}