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;
}
treap模版代码