#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include <cstdlib>
using namespace std;
int n,i,m,h[30009];
struct wbysr
{
wbysr *l,*r;
int dui;
int num;
int size;
wbysr (int x)
{
l=NULL;
r=NULL;
dui=rand()%10000+4;
num=x;
}
}*root;
int size_l(wbysr *t)
{
if(t->l)
return t->l->size;
else
return 0;
}
int size_r(wbysr *t)
{
if(t->r)
return t->r->size;
else
return 0;
}
void rotate_left(wbysr *&t)//左旋,右孩子变成根,根变成左孩子
{
wbysr *p=t->r;
t->r=p->l;
p->l=t;
p->size=t->size;
t->size=size_l(t)+size_r(t)+1;
t=p;
}
void rotate_right(wbysr *&t)
{
wbysr *p=t->l;
t->l = p->r;
p->r = t;
p->size = t->size;
t->size=size_l(t)+size_r(t)+1;
t=p;
}
int ask(int d,wbysr *t)
{
int p=size_l(t);
if(d==p+1)
return t->num;
else
if(d<=p)
return ask(d,t->l);
else
return ask(d-1-p,t->r);
}
void insert(wbysr *&t,int d)
{
if(!t)
{
t=new wbysr(d);
t->size=1;
}
else
if(d<=t->num)
{
t->size++;
insert(t->l,d);
if(t->l->dui < t->dui)
rotate_right(t);
}
else
//if(d>t->num)
{
t->size++;
insert(t->r,d);
if(t->r->dui < t->dui)
rotate_left(t);
}
}
int main()
{
cin>>n>>m;
int now=1;
for(i=1;i<=n;i++)
scanf("%d",&h[i]);
for(i=1;i<=m;i++)
{
int x;
scanf("%d",&x);
while(now<=x)
{
insert(root,h[now]);
now++;
}
cout<<ask(i,root)<<endl;
}
}
很简单的题目。之前就用priority_queue水过,现在由于要学treap又没有很水的题入门所以就他了。。
但是写完真的觉得treap不算很难啊,按的标程学的,基本没有什么障碍;从明天开始多做一些treap的题
最后能写下fhq的函数版treap
下面是代码