SBT

const int maxn=50010;
const int INF=0x3f3f3f3f;
struct SBT  
{  
    int key,left,right,size;  
} tree[maxn];  
  
int root,top;  
  
void left_rot(int &x)  
{  
    int y = tree[x].right;  
    tree[x].right = tree[y].left;  
    tree[y].left = x;  
    tree[y].size = tree[x].size;//转上去的节点数量为先前此处节点的size  
    tree[x].size = tree[tree[x].left].size + tree[tree[x].right].size + 1;  
    x = y;  
}  
  
void right_rot(int &x)  
{  
    int y = tree[x].left;  
    tree[x].left = tree[y].right;  
    tree[y].right = x;  
    tree[y].size = tree[x].size;  
    tree[x].size = tree[tree[x].left].size + tree[tree[x].right].size + 1;  
    x = y;  
}  
  
void maintain(int &x,bool flag)  
{  
    if(flag == false)//左边  
    {  
        if(tree[tree[tree[x].left].left].size > tree[tree[x].right].size)//左孩子的左子树大于右孩子  
            right_rot(x);  
        else if(tree[tree[tree[x].left].right].size > tree[tree[x].right].size)//右孩子的右子树大于右孩子  
        {  
            left_rot(tree[x].left);  
            right_rot(x);  
        }  
        else return;  
    }  
    else //右边  
    {  
        if(tree[tree[tree[x].right].right].size > tree[tree[x].left].size)//右孩子的右子树大于左孩子  
            left_rot(x);  
        else if(tree[tree[tree[x].right].left].size > tree[tree[x].left].size)//右孩子的左子树大于左孩子  
        {  
            right_rot(tree[x].right);  
            left_rot(x);  
        }  
        else return;  
    }  
    maintain(tree[x].left,false);  
    maintain(tree[x].right,true);  
    maintain(x,true);  
    maintain(x,false);  
}  
  
/* 
*insert没有合并相同的元素,如果出现相同的元素则把它放到右子树上,这样能保证求第k小数的时候对相同元素也能正确 
*/  
void insert(int &x,int key)  
{  
    if(x == 0)  
    {  
        x = ++top;  
        tree[x].left = tree[x].right = 0;  
        tree[x].size = 1;  
        tree[x].key = key;  
    }  
    else  
    {  
        tree[x].size ++;  
        if(key < tree[x].key) insert(tree[x].left,key);  
        else  insert(tree[x].right,key);//相同元素插入到右子树中  
        maintain(x, key >= tree[x].key);//每次插入把平衡操作压入栈中  
    }  
}  
  
int del(int &p,int w)  
{  
    if (tree[p].key==w || (tree[p].left==0 && w<tree[p].key) || (tree[p].right==0 && w>tree[p].key))  
    {  
        int delnum=tree[p].key;  
        if (tree[p].left==0 || tree[p].right==0) p=tree[p].left+tree[p].right;  
        else tree[p].key=del(tree[p].left,INF);  
        return delnum;  
    }  
    if (w<tree[p].key) return del(tree[p].left,w);  
    else return del(tree[p].right,w);  
}  
  
int  remove(int &x,int key)  
{  
    int d_key;  
    //if(!x) return 0;  
    tree[x].size --;  
    if((key == tree[x].key)||(key < tree[x].key && tree[x].left == 0) ||  
            (key>tree[x].key && tree[x].right == 0))  
    {  
        d_key = tree[x].key;  
        if(tree[x].left && tree[x].right)  
        {  
            tree[x].key = remove(tree[x].left,tree[x].key+1);  
        }  
        else  
        {  
            x = tree[x].left + tree[x].right;  
        }  
    }  
    else if(key > tree[x].key)  
        d_key = remove(tree[x].right,key);  
    else if(key < tree[x].key)  
        d_key = remove(tree[x].left,key);  
    return d_key;  
}  
  
int getmin()  
{  
    int x;  
    for(x = root ; tree[x].left; x = tree[x].left);  
    return tree[x].key;  
}  
  
int getmax()  
{  
    int x;  
    for(x = root ; tree[x].right; x = tree[x].right);  
    return tree[x].key;  
}  
  
int select(int &x,int k)//求第k小数  
{  
    int r = tree[tree[x].left].size + 1;  
    if(r == k) return tree[x].key;  
    else if(r < k) return select(tree[x].right,k - r);  
    else return select(tree[x].left,k);  
}  
  
int rank(int &x,int key)//求key排第几  
{  
    if(key < tree[x].key)  
        return rank(tree[x].left,key);  
    else if(key > tree[x].key)  
        return rank(tree[x].right,key) + tree[tree[x].left].size + 1;  
    return tree[tree[x].left].size + 1;  
}  
  
int pred(int &x,int y,int key)//前驱 小于  
{  
    if(x == 0) return y;  
    if(tree[x].key < key)  
        return pred(tree[x].right,x,key);  
    else return pred(tree[x].left,y,key);  
}  
  
int succ(int &x,int y,int key)//后继 大于  
{  
    if(x == 0) return y;  
    if(tree[x].key > key)  
        return succ(tree[x].left,x,key);  
    else return succ(tree[x].right,y,key);  
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值