主席树学习链接:https://blog.csdn.net/weixin_43914593/article/details/108861279#comments_13569118
静态区间第k小板子:
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+100;
typedef int LL;
LL a[maxn],b[maxn],root[maxn],cnt=0;
struct Tree{
LL l,r,sum;
}tree[maxn*20];
LL update(LL pre,LL pl,LL pr,LL x)
{
LL rt=++cnt;
tree[rt].l=tree[pre].l;
tree[rt].r=tree[pre].r;
tree[rt].sum=tree[pre].sum+1;
LL mid=(pl+pr)>>1;
if(pl!=pr){
if(x<=mid)
{
tree[rt].l=update(tree[pre].l,pl,mid,x);
}
else tree[rt].r=update(tree[pre].r,mid+1,pr,x);
}
return rt;
}
LL query(LL u,LL v,LL pl,LL pr,LL k)
{
if(pl==pr) return pl;
LL res=tree[tree[v].l].sum-tree[tree[u].l].sum;
LL mid=(pl+pr)>>1;
if(res>=k){
return query(tree[u].l,tree[v].l,pl,mid,k);
}
else return query(tree[u].r,tree[v].r,mid+1,pr,k-res);
}
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL n,m;cin>>n>>m;
for(LL i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i];
}
sort(b+1,b+1+n);
int siz=unique(b+1,b+1+n)-b-1;
///root[0]=update()没必要建空树,会卡常的,今年省赛就卡了
for(LL i=1;i<=n;i++){///建立n棵线段树
int x=lower_bound(b+1,b+1+siz,a[i])-b;
root[i]=update(root[i-1],1,siz,x);
}
while(m--)
{
LL l,r,k;cin>>l>>r>>k;
LL t=query(root[l-1],root[r],1,siz,k);
cout<<b[t]<<endl;
}
return 0;
}