treap插入、删除、查询时间复杂度均为O(logn)
treap树中每个节点有两种权值:键值和该节点优先值
如果只看优先值,这棵树又是一个堆
treap有两种平衡方法:左旋&右旋
insert 插入
remove 删除
_find 查找
kth 返回root为根的树中第k大的元素
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cstdio>
using namespace std; struct Node
{
Node* ch[];
int r,v,s; //r:随机优先级,v:值,s:以本节点为根的子树的结点总数
bool operator < (const Node& rhs)
{
return (r<rhs.r);
}
int cmp(int x)
{
if (x==v) return -;
return x<v?:;
}
void maintain()
{
s=;
if (ch[]!=NULL) s+=ch[]->s;
if (ch[]!=NULL) s+=ch[]->s;
}
Node (int v):v(v) //结构体的构造函数
{
ch[]=ch[]=NULL;
r=rand();
s=;
}
}; void rotate(Node* &o,int d)
{
Node* k=o->ch[d^];
o->ch[d^]=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
{
//int d=o->cmp(x); //不用cmp
int d=(x < o->v ? : );
insert(o->ch[d],x);
if (o->ch[d]->r > o->r)
rotate(o,d^);
}
o->maintain();
} void remove(Node* &o,int x)
{
int d=o->cmp(x);
if (d==-)
{
Node *u=o;
if ((o->ch[]!=NULL) && (o->ch[]!=NULL))
{
int d2=(o->ch[]->r > o->ch[]->r ? : );
rotate(o,d2);
remove(o->ch[d2],x);
}
else
{
if (o->ch[]==NULL)
o=o->ch[];
else
o=o->ch[];
delete u;
}
}
else
remove(o->ch[d],x);
if (o!=NULL)
o->maintain();
} int kth(Node* o,int k)
{
if ((o==NULL)||(k<=)||(k > o->s))
return ;
int s=(o->ch[]==NULL ? : o->ch[]->s);
if (k==s+)
return o->v;
else if (k<=s)
return kth(o->ch[],k);
else
return kth(o->ch[],k-s-); } int _find(Node* o,int x)
{
while (o!=NULL)
{
int d=o->cmp(x);
if (d==-)
return ;
else
o=o->ch[d];
}
return ;
} int main()
{
//freopen("in.txt","r",stdin); int n,m,opr,x;
srand(time());
cin>>n;
Node* root=new Node();
for (int i=;i<=n;i++)
{
cin>>opr>>x;
if (opr==)
{
insert(root,x);
}
else if (opr==)
{
if (!_find(root,x))
cout<<"Not Found,Operation Failed"<<endl;
else
remove(root,x);
}
}
cout<<"-----------------"<<endl;
cin>>m;
for (int i=;i<=m;i++)
{
cin>>x;
if (_find(root,x))
cout<<"Found"<<endl;
else
cout<<"Not Found"<<endl;
}
cout<<"-----------------"<<endl;
cin>>m;
for (int i=;i<=m;i++)
{
cin>>x;
int ans=kth(root,x);
cout<<x<<"th: "<<ans<<endl;
}
}
PS:发现一个画图论图形的神器:GraphViz