题面
思路
平衡树裸题,直接上板子。每次添加的时候 add ,查询的时候输出第 I 小的并更新 I 即可。
代码
#include<bits/stdc++.h>
using namespace std;
struct node{
long long x,y,l,r,size,cnt;
};
node s[1000001];
long long n,q,top=0;
long long root=0;
void update(long long x){
s[x].size=s[s[x].l].size+s[s[x].r].size+s[x].cnt;
}
void rotr(long long &x){
long long l=s[x].l;
s[x].l=s[l].r;
s[l].r=x;
s[l].size=s[x].size;
update(x);
x=l;
}
void rotl(long long &x){
long long r=s[x].r;
s[x].r=s[r].l;
s[r].l=x;
s[r].size=s[x].size;
update(x);
x=r;
}
void add(long long &x,long long data){
if (!x){
x=++top;
s[x].x=data;
s[x].y=rand()%19260817;
s[x].cnt=1;
s[x].size=1;
s[x].l=0;
s[x].r=0;
return;
}
s[x].size++;
if (s[x].x==data){
s[x].cnt++;
}else if (data<s[x].x){
add(s[x].l,data);
if (s[x].y>s[s[x].l].y){
rotr(x);
}
}else{
add(s[x].r,data);
if (s[x].y>s[s[x].r].y){
rotl(x);
}
}
}
void del(long long &x,long long data){
if (s[x].x==data){
if (s[x].cnt>1){
s[x].cnt--;
s[x].size--;
return;
}
if (!s[x].l||!s[x].r){
x=s[x].l+s[x].r;
return;
}
if (s[s[x].l].y<s[s[x].r].y){
rotr(x);
del(x,data);
}else{
rotl(x);
del(x,data);
}
return;
}
s[x].size--;
if (data<s[x].x){
del(s[x].l,data);
}else{
del(s[x].r,data);
}
}
long long pre(long long data){
long long now=root,res=-2147483647;
while (now){
if (s[now].x<data){
res=s[now].x;
now=s[now].r;
}else{
now=s[now].l;
}
}
return res;
}
long long nxt(long long data){
long long now=root,res=2147483647;
while (now){
if (s[now].x>data){
res=s[now].x;
now=s[now].l;
}else{
now=s[now].r;
}
}
return res;
}
long long querykth(long long k){
long long now=root;
while (now){
if (s[s[now].l].size<k&&s[s[now].l].size+s[now].cnt>=k){
return s[now].x;
}
if (s[s[now].l].size>=k){
now=s[now].l;
}else{
k-=s[s[now].l].size+s[now].cnt;
now=s[now].r;
}
}
return 0;
}
long long queryrank(long long data){
long long now=root,res=0;
while (now){
if (data==s[now].x){
return res+s[s[now].l].size+1;
}
if (data<s[now].x){
now=s[now].l;
}else{
res+=s[s[now].l].size+s[now].cnt;
now=s[now].r;
}
}
return res;
}
int a[1000000],b[1000000],I=0;
int m;
int main(){
srand(time(0));
cin>>q>>m;
long long t,x;
for (int i=1;i<=q;i++){
cin>>a[i];
}
for (int i=1;i<=m;i++){
cin>>b[i];
}
for (int i=1;i<=q;i++){
add(root,a[i]);
while (i==b[I+1]){
I++;
cout<<querykth(I)<<endl;
}
}
}
