Treap模板

几篇学习Treap的博客

平衡树Treap的方法与应用

fhp式的treap

挖掘Treap的潜力

非旋转Treap及可持久化[Merge,Split]



指针版

struct Node
{
    Node *ch[2];
    int r;//优先级
    int v;//值
    int s;
    int cnt;//自身重复次数
    Node(int val){v=val;ch[0]=ch[1]=NULL;s=cnt=1;r=rand();}
    bool operator < (const Node &a)const
    {
        return r<a.r;
    }
    int cmp(int x)const
    {
        if(x==v)return -1;
        return x<v?0:1;
    }
    void maintain()
    {
        s=cnt;
        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 insert(Node* &o,int x)
{
    if(o==NULL)o=new Node(x);
    else
    {
        if(x==o->v)o->cnt++;
        else
        {
            int d=(x<o->v?0:1);
            insert(o->ch[d],x);
            if(o->ch[d]>o)rotate(o,d^1);
        }
    }
    o->maintain();
}
void remove(Node* &o,int x)
{
    if(o==NULL)return;
    int d=o->cmp(x);
    if(d==-1)
    {
        Node *u=o;
        if(o->ch[0]!=NULL&&o->ch[1]!=NULL)
        {
            int d2=(o->ch[0]>o->ch[1]?1:0);
            rotate(o,d2);
            remove(o->ch[d2],x);
        }
        else
        {
            if(o->ch[0]==NULL)o=o->ch[1];
            else o=o->ch[0];
            delete u;
        }
    }
    else remove(o->ch[d],x);
    if(o)o->maintain();
}
//返回最大值
int get_max(Node *o)
{
    while(o->ch[0])o=o->ch[0];
    return o->v;
}
//返回最小值
int get_min(Node *o)
{
    while(o->ch[1])o=o->ch[1];
    return o->v;
}
//返回val的前驱,如果没有的话返回y
//y的初值可赋成0,表示没有前驱
int get_pred(Node *o,int val,int y)
{
    if(!o)return y;
    if(o->v<=val)//注意大于等于号
        return get_pred(o->ch[1],val,o->v);
    else return get_pred(o->ch[0],val,y);
}
//返回val的后继,如果没有的话返回y
//y的初值可赋成0,表示没有后继
int get_succ(Node *o,int val,int y)
{
    if(!o)return y;
    if(o->v>=val)return get_succ(o->ch[0],val,o->v);
    else return get_succ(o->ch[1],val,y);
}
//返回第k大的元素的值
int get_kth(Node *o,int k)
{
    int lsize=(o->ch[0]!=NULL?o->ch[0]->s:0);
    if(k<=lsize)return get_kth(o->ch[0],k);
    else if(k>lsize+o->cnt)
        return get_kth(o->ch[1],k-lsize-o->cnt);
    return o->v;
}
//返回val的排名
int get_rank(Node *&o,int val)
{
    if(!o)return 0;
    int lsize=(o->ch[0]?o->ch[0]->s:0);
    if(val<o->v)
        return get_rank(o->ch[0],val);
    else if(val>o->v)
        return get_rank(o->ch[1],val)+lsize+o->cnt;
    return lsize+1;
}

数组版:

struct Node
{
    int ch[2];
    int r;//优先级
    int v;//值
    int s;
    int cnt;//自身重复次数
    void init(int val){v=val;ch[0]=ch[1]=0;s=cnt=1;r=rand();}
    int cmp(int x)const
    {
        if(x==v)return -1;
        return x<v?0:1;
    }

}tree[maxn];
void maintain(int x)
{
    tree[x].s=tree[x].cnt;
    tree[x].s+=tree[tree[x].ch[0]].s+tree[tree[x].ch[1]].s;
}
void rotate(int &o,int d)
{
    int k=tree[o].ch[d^1];
    tree[o].ch[d^1]=tree[k].ch[d];
    tree[k].ch[d]=o;
    maintain(o);
    maintain(k);
    o=k;
}
void insert(int &o,int x)
{
    if(!o)
    {
        o=++tot;
        tree[o].init(x);
    }
    else
    {
        if(x==tree[o].v)tree[o].cnt++;
        else
        {
            int d=(x<tree[o].v?0:1);
            insert(tree[o].ch[d],x);
            if(tree[tree[o].ch[d]].r>tree[o].r)
                rotate(o,d^1);
        }
    }
    maintain(o);
}
void remove(int &o,int x)
{
    if(!o)return;
    int d=tree[o].cmp(x);
    if(d==-1)
    {
        int u=o;
        if(tree[o].cnt>1)tree[o].cnt--;
        else if(tree[o].ch[0]&&tree[o].ch[1])
        {
            int d2=(tree[tree[o].ch[0]].r>tree[tree[o].ch[1]].r?1:0);
            rotate(o,d2);
            remove(tree[o].ch[d2],x);
        }
        else
        {
            if(!tree[o].ch[0])o=tree[o].ch[1];
            else o=tree[o].ch[0];
        }
    }
    else remove(tree[o].ch[d],x);
    if(o)maintain(o);
}
//返回最大值
int get_max(int o)
{
    while(tree[o].ch[0])o=tree[o].ch[0];
    return tree[o].v;
}
//返回最小值
int get_min(int o)
{
    while(tree[o].ch[1])o=tree[o].ch[1];
    return tree[o].v;
}
//返回val的前驱,如果没有的话返回y
//y的初值可赋成0,表示没有前驱
int get_pred(int o,int val,int y)
{
    if(!o)return y;
    if(tree[o].v<=val)//注意大于等于号
        return get_pred(tree[o].ch[1],val,tree[o].v);
    else return get_pred(tree[o].ch[0],val,y);
}
//返回val的后继,如果没有的话返回y
//y的初值可赋成0,表示没有后继
int get_succ(int o,int val,int y)
{
    if(!o)return y;
    if(tree[o].v>=val)return get_succ(tree[o].ch[0],val,tree[o].v);
    else return get_succ(tree[o].ch[1],val,y);
}
//返回第k大的元素的值
int get_kth(int o,int k)
{
    if(!o)return 0;
    if(k<=tree[tree[o].ch[0]].s)return get_kth(tree[o].ch[0],k);
    else if(k>tree[tree[o].ch[0]].s+tree[o].cnt)
        return get_kth(tree[o].ch[1],k-tree[tree[o].ch[0]].s-tree[o].cnt);
    return tree[o].v;
}
//返回val的排名
int get_rank(int o,int val)
{
    if(!o)return 0;
    int lsize=tree[tree[o].ch[0]].s;
    if(val<tree[o].v)
        return get_rank(tree[o].ch[0],val);
    else if(val>tree[o].v)
        return get_rank(tree[o].ch[1],val)+lsize+tree[o].cnt;
    return lsize+tree[o].cnt;
}


fhp式的Treap

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=1000;
struct Node
{
    int val,size,r,cnt;
    Node *left,*right;
    Node(int value)
    {
        val=value;
        size=1;
        left=right=NULL;
        r=rand();
    }
    void maintain()
    {
        size=1;
        if(left)size+=left->size;
        if(right)size+=right->size;
    }

};
Node *root;
Node *merge(Node *A,Node *B)
{
    if(!A)return B;
    if(!B)return A;
    if(A->r<B->r)
    {
        A->right=merge(A->right,B);
        A->maintain();
        return A;
    }
    else
    {
        B->left=merge(A,B->left);
        B->maintain();
        return B;
    }
}
pair<Node *,Node *> split(Node *x,int k)
{
    if(!x)return pair<Node *,Node *>(NULL,NULL);
    pair<Node *,Node *>y;
    int lsize=(x->left?x->left->size:0);
    if(lsize>=k)
    {
        y=split(x->left,k);
        x->left=y.second;
        x->maintain();
        y.second=x;
    }
    else
    {
        y=split(x->right,k-lsize-1);
        x->right=y.first;
        x->maintain();
        y.first=x;
    }
    return y;
}
Node *build(int a[])
{
    Node *stack[maxn],*x,*last;
    int p=0;
    for(int i=1;i<a[0];i++)
    {
        x=new Node(a[i]);
        last=NULL;
        while(p&&stack[p]->r>x->r)
        {
            stack[p]->maintain();
            last=stack[p];
            stack[p--]=NULL;
        }
        if(p)stack[p]->right=x;
        x->left=last;
        stack[++p]=x;
    }
    while(p)stack[p--]->maintain();
    return stack[1];
}
int get_kth(int k)
{
    pair<Node *,Node *> x=split(root,k-1);
    pair<Node *,Node *> y=split(x.second,1);
    Node *ans=y.first;
    root=merge(merge(x.first,ans),y.second);
    return ans->val;
}
int get_rank(Node *x,int v)
{
    if(!x)return 0;
    if(v<x->val)return get_rank(x->left,v);
    else
        return get_rank(x->right,v)+(x->left?x->left->size:0)+1;
}
void insert(int v)
{
    int k=get_rank(root,v);
    pair<Node *,Node *> x=split(root,k);
    Node *p=new Node(v);
    root=merge(merge(x.first,p),x.second);
}
void del(int k)
{
    pair<Node *,Node*> x=split(root,k-1);
    pair<Node *,Node*> y=split(x.second,1);
    root=merge(x.first,y.second);
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值