话不多说,直接进入正题。
一:基本保存信息
struct node
{
int key,val;//val为权值,key为真实值
int l,r;//左右儿子的编号
int size;//树的大小
}tr[N];
二:构造新节点
int newnode(int v)
{
tr[++idx].val=v;
tr[idx].key=rand();
tr[idx].size=1;
return idx;
}
三:向上更新
void pushup(int p)
{
tr[p].size=tr[tr[p].l].size+tr[tr[p].r].size+1;
}
四:分裂
void split(int p,int v,int &x,int &y)
{
if(!p) x=y=0,return ;
if(tr[p].val<=v)
{
x=p;
split(tr[x].r,v,tr[x].r,y);
}
else
{
y=p;
split(tr[y].l,v,x,tr[y].l);
}
pushup(p);
}
五:合并
int merge(int x,int y)
{
if(!x || !y)
{
return x+y;
}
if(tr[x].key<tr[y].key)
{
tr[x].r=merge(tr[x].r,y);
pushup(x);
return x;
}
else
{
tr[y].l=merge(x,tr[y].l);
pushup(y);
return y;
}
}
六:插入
int newnode(int v)
{
tr[++idx].val=v;
tr[idx].key=rand();
tr[idx].size=1;
return idx;
}
void insert(int v)
{
int x,y,z;
split(root,v,x,y);
z=newnode(v);
root = merge(merge(x,z),y);
}
七:删除
void del(int v)
{
int x,y,z;
split(root,v,x,z);
split(x,v-1,x,y);
y=merge(tr[y].l,tr[y].r);
root=merge((x,y),z);
}
八:返回第K个节点
int get_k(int p,int k)
{
if(k<=tr[tr[p].l].size)
{
return get_k(tr[p].l,k);
}
if(k==tr[tr[p].l].size+1) return p;
return get_k(tr[p].r,k-tr[tr[p].l].size-1);
}
九:返回前驱
void grt_pre(int v)
{
int x,y;
split(root,v-1,x,y);
int p=get_k(x,tr[x].size());
printf("%d\n",tr[p].val);
merge(x,y);
}
十:返回后驱
void get_suc(int v)
{
int x,y;
split(root,v,x,y);
int p=get(x,1);
printf("%d\n",tr[p].val);
root=merge(x,y);
}
十一:得到排名
void get_rank(int v)
{
int x,y;
split(root,v-1,x,y);
printf("%d\n",tr[x].size+1);
root=merge(x,y);
}
十二:得到第k个数
int get_val(int v)
{
int p = get_k(root,k);
printf("%d\n",tr[p].val);
}