一个简化版的treap打版题,也当练练手。这个版来自百度百科。。。。。不知道数据大了效果怎么样。
主要是动态插入和查询。
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#define maxv 100005
using namespace std;
struct tree
{
int left,right;
int size,value,fix;
}node[maxv];
int n,m,regis[maxv],nume=1,root=-1;
void update(int k)
{
node[k].size=node[node[k].left].size+node[node[k].right].size+1;
}
void lturn(int &k)
{
int t=node[k].right;
node[k].right=node[t].left;
node[t].left=k;
node[t].size=node[k].size;
update(k);
k=t;
}
void rturn(int &k)
{
int t=node[k].left;
node[k].left=node[t].right;
node[t].right=k;
node[t].size=node[k].size;
update(k);
k=t;
}
void insert(int &x,int tkey)
{
if (x==-1)
{
nume++;x=nume;
node[nume].size=1;
node[nume].value=tkey;
node[nume].left=-1;
node[nume].right=-1;
node[nume].fix=rand();
}
else
{
node[x].size++;
if (tkey<node[x].value)
{
insert(node[x].left,tkey);
if (node[node[x].left].fix<node[x].fix) rturn(x);
}
else
{
insert(node[x].right,tkey);
if (node[node[x].right].fix<node[x].fix) lturn(x);
}
}
}
int rank(int k,int x)
{
if (k==-1) return 0;
else
{
if (x<=node[node[k].left].size)
return rank(node[k].left,x);
else if (x>node[node[k].left].size+1)
return rank(node[k].right,x-node[node[k].left].size-1);
else return node[k].value;
}
}
int main()
{
srand(time(0));
while (scanf("%d%d",&n,&m)==2)
{
for (int i=1;i<=n;i++)
scanf("%d",®is[i]);
int k,l=1;
for (int i=1;i<=m;i++)
{
scanf("%d",&k);
while (l<=k)
{
insert(root,regis[l]);
l++;
}
printf("%d
",rank(root,i));
}
}
return 0;
}