poj 1442 名次树

时间:2023-03-08 19:46:16
poj 1442    名次树

这回要求的是第k的元素,

参考了ljl大神的模板,orz

 //insert 插入
//remove 删除
//_find 查找
//kth 返回root为根的树中第k小的元素
//treap插入、删除、查询时间复杂度均为O(logn)
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cstdio>
using namespace std;
int a[],n,m;
struct Node
{
Node *ch[];
int r,v,s;
Node(int v):v(v)
{s=;ch[]=ch[]=NULL;r=rand();}
int cmp(int x) const{
if(x==v)return(-);
return (x<v)?():();
}
void maintain(){
s=;
if(ch[]!=NULL)s+=ch[]->s;
if(ch[]!=NULL)s+=ch[]->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=(x<o->v)?:;
insert(o->ch[d],x);
if((o->r)<(o->ch[d]->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=o->ch[];delete u;}else
if(o->ch[]==NULL){o=o->ch[];delete u;}else {
int c=(o->ch[])>(o->ch[])?():();
rotate(o,c);
remove(o->ch[c],x);
}
}
else remove(o->ch[d],x);
if(o!=NULL) o->maintain();
}
int find(Node* &o,int x)
{
while(o!=NULL){
int d=o->cmp(x);
if(d==-)
return ;
else
o=o->ch[d];
}
return ;
}
int kth(Node* o,int k)
{
while(o!=NULL){
int lchsize=(o->ch[]!=NULL)?
(o->ch[]->s):;
if(lchsize+==k)
return o->v;
else {
int d=(lchsize<k);
o=o->ch[d];
k-=d*(lchsize+);
}
}
return ;
} int main()
{
Node* root=NULL;
int u,ans,p=;
srand(time()); cin>>m>>n;
for(int i=;i<m;i++)
cin>>a[i];
for(int i=;i<=n;i++)
{
cin>>u;
while(p<u)
insert(root,a[p++]);
ans=kth(root,i);
cout<<ans<<endl;
}
return ;
}