谴责奶人的HSZ巨神
静态版本 求区间第k大
可持久化也没那么高大上嘛,主席树本质上就是多棵线段树,求第k大就类似平衡树的第k大。
//Stay foolish,stay hungry,stay young,stay simple
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
using namespace std;
const int MAXN=200009,M=5000009;
int P,a[MAXN],b[MAXN],rt[MAXN],lc[M],rc[M],s[M];
inline int rd(){
int ret=0,f=1;char c;
while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
while(isdigit(c)){
ret=ret*10+c-'0';
c=getchar();
}
return ret*f;
}
int n,m;
void build(int&t,int l,int r)
{
t=++P;
if(l!=r)
{
int m=(l+r)>>1;
build(lc[t],l,m);
build(rc[t],m+1,r);
}
}
inline void insert(int*t,int u,int l,int r,int v)
{
while(l!=r)
{
s[*t=++P]=s[u]+1;
int m=(l+r)>>1;
if(v<=m) r=m,rc[*t]=rc[u],t=&lc[*t],u=lc[u];
else l=m+1,lc[*t]=lc[u],t=&rc[*t],u=rc[u];
}
s[*t=++P]=s[u]+1;
}
inline int ask(int t,int u,int l,int r,int k)
{
while(l!=r)
{
int m=(l+r)>>1;
int v=s[lc[u]]-s[lc[t]];
if(k<=v) r=m,t=lc[t],u=lc[u];
else l=m+1,t=rc[t],u=rc[u],k-=v;
}
return b[l];
}
int main()
{
n=rd();
m=rd();
for(int i=1;i<=n;i++)
a[i]=rd(),b[i]=a[i];
sort(b+1,b+n+1);
int tot=unique(b+1,b+n+1)-b-1;//离散化
build(rt[0],1,tot);
for(int i=1;i<=n;i++)
insert(&rt[i],rt[i-1],1,tot,lower_bound(b+1,b+tot+1,a[i])-b);
for(int i=1;i<=m;i++){
int x,y,k;
x=rd();y=rd();k=rd();
printf("%d\n",ask(rt[x-1],rt[y],1,tot,k));
}
return 0;
}