首页 > 代码库 > treap模版代码

treap模版代码

treap模版暂存。

以后修改整理。

#include<cstdio>
#include<iostream>
#include <time.h>
#include<cstdlib>

using namespace std;
struct Node
{
    Node *ch[2];//左右子树
    int r;//优先级。数值越大,优先级越高
    int v;//
    int cmp(int x)const
    {
        if(x==v) return -1;
        return x<v?0:1;
    }
};
/*
旋转操作:
1.取出新的根节点。左旋:取原根的右孩子;右旋:取原根的左孩子
2.左旋:原根的右孩子的左孩子取代之;右旋:原根的左孩子的右孩子取代之
3.左旋:原根成为新根的左孩子;右旋:原根成为新根的右孩子
4.将更新返回的根节点
旋转左右是根据原根结点的位置变化方向而定的
*/
void rotate(Node* &o,int d)//d=0代表左旋,d=1代表右旋
{
    Node *k=o->ch[d^1];//左旋时d^1得到1右孩子,右旋时d^1得到0左孩子,取出该结点
    o->ch[d^1]=k->ch[d]; //孩子的左(右)孩子取代孩子位置
    k->ch[d]=o;//原根结点成为右(左)结点的左(右)孩子
    o=k;//孩子结点取代原根节点位置,保证返回值是新的根结点
}

void insert(Node* &o,int x)//在以o为根的子树中插入键值x,修改o
{
    if(o==NULL)
    {
        o=new Node();
        o->ch[0]=o->ch[1]=NULL;
        o->v=x;
        o->r=rand();
    }
    else
    {
        int d=o->cmp(x);
        insert(o->ch[d],x);
        if(o->ch[d]->r > o->r) rotate(o,d^1);
    }
}
void remove(Node* &o,int x)
{
    int d=o->cmp(x);
    if(d==-1)
    {
        if(o->ch[0]==NULL) o=o->ch[1];
        else if(o->ch[1]==NULL) o=o->ch[0];
        else
        {
            int d2=(o->ch[0]->r > o->ch[1]->r)?1:0;
            rotate(o,d2);
            remove(o->ch[d2],x);
        }
    }
    else remove(o->ch[d],x);
}
bool find(Node* o,int x)
{
    while(o!=NULL)
    {
        int d=o->cmp(x);
        if(d==-1) return true;
        else o=o->ch[d];
    }
    return false;
}
Node *head;

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; ++i)
    {
        int t;
        scanf("%d",&t);
        insert(head,t);
    }
    int p;
    cout<<"===="<<endl;
    while(scanf("%d",&p)!=EOF)
    {
        int t;
        scanf("%d",&t);
        switch(p)
        {
        case 0:
            cout<<find(head,t)<<endl;
            break;
        case 1:
            insert(head,t);
            break;
        case 2:
            remove(head,t);
            break;

        }
    }
    return 0;
}