K-th Number
题意:求区间第k小的数。
思路:主席树模板题。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
int a[maxn],b[maxn];
int rt[maxn*20],ls[maxn*20],rs[maxn*20],sum[maxn*20];
int cnt,ql,qr,k;
void up(int pre,int& o,int l,int r,int pos){
o=++cnt;
ls[o]=ls[pre];
rs[o]=rs[pre];
sum[o]=sum[pre]+1;
if(l==r)
return;
int m=(l+r)>>1;
if(pos<=m)
up(ls[pre],ls[o],l,m,pos);
else up(rs[pre],rs[o],m+1,r,pos);
}
int qu(int pre,int o,int l,int r){
if(l==r)
return b[l];
int m=(l+r)>>1;
int cmp=sum[ls[o]]-sum[ls[pre]];
if(cmp>=k)
return qu(ls[pre],ls[o],l,m);
else{
k-=cmp;
return qu(rs[pre],rs[o],m+1,r);
}
}
int main(){
std::ios::sync_with_stdio(false);
int n,q;
while(cin>>n>>q){
for(int i=1;i<=n;i++){
cin>>b[i];
a[i]=b[i];
}
sort(b+1,b+n+1);
int sz=unique(b+1,b+1+n)-b-1;
cnt=0;
for(int i=1;i<=n;i++)
a[i]=lower_bound(b+1,b+1+sz,a[i])-b;
for(int i=1;i<=n;i++)
up(rt[i-1],rt[i],1,sz,a[i]);
while(q--){
cin>>ql>>qr>>k;
cout<<qu(rt[ql-1],rt[qr],1,sz)<<"\n";
}
}
}