您的位置:首页 > 其它

poj 1442 Treap实现名次树

2015-08-02 10:26 316 查看
Treap的入门题目,每个结点多维护一个size表示以它为根的子树的结点数,然后查kth的时候一层一层向下即可。

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

struct Node
{
Node * ch[2];
int r;
int v;
int s;
int cmp( int x )
{
if ( x == v ) return -1;
return x < v ? 0 : 1;
}
void maintain()
{
s = 1;
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();
o->ch[0] = o->ch[1] = NULL;
o->v = x;
o->r = rand();
o->s = 1;
}
else
{
int d = ( x < o->v ? 0 : 1 );
insert( o->ch[d], x );
if ( o->ch[d]->r > o->r )
{
rotate( o, d ^ 1 );
}
o->maintain();
}
}

int kth( Node * o, int k )
{
int tmp = ( o->ch[0] == NULL ? 0 : o->ch[0]->s );
if ( k == tmp + 1 ) return o->v;
else if ( k < tmp + 1 ) return kth( o->ch[0], k );
else return kth( o->ch[1], k - tmp - 1 );
}

const int N = 30001;
int a
;

int main ()
{
int n, m;
while ( scanf("%d%d", &n, &m) != EOF )
{
Node * root = NULL;
for ( int i = 1; i <= n; i++ )
{
scanf("%d", a + i);
}
int tt, cnt = 1;
for ( int i = 1; i <= m; i++ )
{
scanf("%d", &tt);
while ( cnt <= tt )
{
insert( root, a[cnt++] );
}
printf("%d\n", kth( root, i ));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: