splay树

#include<cstdlib>
struct Node{
    Node* ch[2];
    int s,v,r;
    Node(int v): v(v) {ch[0]=ch[1]=NULL;r=rand();s=1;}
    int cmp(int x) const {
        if(x==s-ch[1]->s) return -1;
        return x<=ch[0]->s?0:1;
    }
    void maintain(){
        s=1;
        if(ch[0]!=NULL) s+=ch[0]->s;
        if(ch[1]!=NULL) s+=ch[1]->s;
    }
};
void rotate(Node* &o,int d)
{
    Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
    o->maintain();k->maintain();o=k;
}
void splay(Node* &o,int k)
{
    int d=o->cmp(k);
    if(d==1) k-=o->ch[0]->s+1;
    if(d!=-1)
    {
        Node* p=o->ch[d];
        int d2=p->cmp(k);
        int k2=(d2==0?k:k-p->ch[0]->s-1);
        if(d2!=-1)
        {
            splay(p->ch[d2],k2);
            if(d==d2) rotate(o,d^1);else rotate(o->ch[d],d);
        }
        rotate(o,d^1);
    }
}
Node* merge(Node* left,Node* right)
{
    splay(left,left->s);
    left->ch[1]=right;
    left->maintain();
    return left;
}
void split(Node* o,int k,Node* &left,Node* &right)
{
    splay(o,k);
    left=o;
    right=o->ch[1];
    o->ch[1]=NULL;
    left->maintain();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值