N个数,在插入第B[i]个数之后,查询当前集合中第i小的数是多少。treap模板题...
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
using namespace std;
typedef long long ll;
const int maxn=101000;
int pre[maxn];
int ch[maxn][2];
int size[maxn];
int ct[maxn];
int pri[maxn];
int key[maxn];
int tot,root;
int cmp(int a,int b)
{
if (a==b) return -1;
if (a<b) return 0;
else return 1;
}
struct TREAP
{
void init()
{
root=0;
memset(pre,0,sizeof pre);
memset(ch,0,sizeof ch);
memset(ct,0,sizeof ct);
memset(size,0,sizeof size);
tot=0;
}
void pushup(int r)
{
size[r]=size[ch[r][0]]+size[ch[r][1]]+ct[r];
}
void rotate(int x,int kind)
{
int k=ch[x][kind^1];
ch[x][kind^1]=ch[k][kind];
pre[ch[k][kind]]=x;
ch[k][kind]=x;
pre[k]=pre[x];
if (pre[x])
{
ch[pre[x]][ch[pre[x]][1]==x]=k;
}
else root=k;
pre[x]=k;
pushup(x);
pushup(k);
}
void newnode(int &r,int father,int k)
{
r=++tot;
pre[r]=father;
pri[r]=rand();
size[r]=1;
ct[r]=1;
key[r]=k;
ch[r][0]=ch[r][1]=0;
}
void insert(int &rt,int x,int father)
{
if (rt==0)
{
newnode(rt,father,x);
}
else
{
int d=cmp(x,key[rt]);
if (d==-1)
{
ct[rt]++;
size[rt]++;
}
else
{
insert(ch[rt][d],x,rt);
pushup(rt);
if (pri[ch[rt][d]]>pri[rt]) rotate(rt,d^1);
}
}
}
void print(int r)
{
if (r==0) return;
print(ch[r][0]);
for (int i=1; i<=ct[r]; i++)
printf("%d ",key[r]);
print(ch[r][1]);
}
void printpri(int r)
{
if (r==0) return;
print(ch[r][0]);
printf("%d ",pri[r]);
print(ch[r][1]);
}
int select(int k)
{
int rt=root;
while(true)
{
if (k<=size[ch[rt][0]]) rt=ch[rt][0];
else if (k<=size[ch[rt][0]]+ct[rt]) break;
else k-=(size[ch[rt][0]]+ct[rt]),rt=ch[rt][1];
}
return rt;
}
}treap;
int n,m;
int a[100600];
int b[100600];
int main()
{
// freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
treap.init();
for (int i=1; i<=n; i++)
scanf("%d",&a[i]);
for (int i=1; i<=m; i++)
scanf("%d",&b[i]);
int pt=1;
for (int i=1; i<=n; i++)
{
treap.insert(root,a[i],0);
// treap.print(root);
// puts("");
while (i==b[pt])
{
int ans=treap.select(pt);
cout<<key[ans]<<endl;
// treap.del(ans);
// treap.insert(root,key[ans]+1,0);
pt++;
}
}
}
return 0;
}