您的位置:首页 > 其它

无旋treap模板 数组版

2017-10-07 09:59 399 查看
简单的找第k大数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<ctime>
using namespace std;

int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
if(c=='-')c=getchar(),f=-1;
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}

const int N=10005;
int n,k,root,L,R;
int a
;
int tot,val
,pri
,size
,son
[2];

int upt(int u)
{
size[u]=size[son[u][0]]+size[son[u][1]]+1;
return u;
}

int merge(int u,int v)
{
if(!u)return upt(v);
if(!v)return upt(u);
if(pri[u]<pri[v])
{
son[u][1]=merge(son[u][1],v);
return upt(u);
}
else
{
son[v][0]=merge(u,son[v][0]);
return upt(v);
}
}

void Split(int u,int v,int &L,int &R)
{
if(!u)
{
L=R=0;
return;
}
if(val[u]<=v)
{
Split(son[u][1],v,L,R);
son[u][1]=0,upt(u);
L=merge(u,L);
}
else
{
Split(son[u][0],v,L,R);
son[u][0]=0,upt(u);
R=merge(R,u);
}
}

int Insert(int u,int v)
{
L=R=0;
Split(u,v,L,R);
val[++tot]=v,pri[tot]=rand();
return merge(merge(L,tot),R);
}

void Split_Kth(int u,int kth,int &L,int &R)
{
if(!u)
{
L=R=0;
return;
}
if(size[son[u][0]]<kth)
{
Split_Kth(son[u][1],kth-size[son[u][0]]-1,L,R);
son[u][1]=0,upt(u);
L=merge(u,L);
}
else
{
Split_Kth(son[u][0],kth,L,R);
son[u][0]=0,upt(u);
R=merge(R,u);
}
}

int main()
{
//freopen("lx.in","r",stdin);
srand(time(
126a9
0));
n=getint(),k=getint();
for(int i=1;i<=n;i++)a[i]=getint();
for(int i=1;i<=n;i++)
root=Insert(root,a[i]);
L=R=0;
Split_Kth(root,k,L,R);
int pos=L;
while(son[pos][1])
pos=son[pos][1];
cout<<val[pos];
root=merge(L,R);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: