设区间为l,r,用r版本减去l版本求出区间第k小,一个板子
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
struct node1
{
int v;
int po;
}ed[500005];
struct node2
{
int v;
int vy;
}ed2[500005];
int cmp(node1 a,node1 b)
{
return a.v<b.v;
}
int cnt;
int root[500005];
int tval[500005];
struct Tree
{
int lson;
int rson;
int val;
}tree[500005*30];
void insert(int &rt,int ort,int l,int r,int po,int val)
{
if(!rt)rt=++cnt;
if(l==r)
{
tree[rt].val=tree[ort].val+val;
return;
}
int mid=(l+r)/2;
if(po<=mid)
{
tree[rt].rson=tree[ort].rson;
insert(tree[rt].lson,tree[ort].lson,l,mid,po,val);
}else
{
tree[rt].lson=tree[ort].lson;
insert(tree[rt].rson,tree[ort].rson,mid+1,r,po,val);
}
tree[rt].val=tree[tree[rt].lson].val+tree[tree[rt].rson].val;
}
int query(int rt,int ort,int l,int r,int k)
{
if(!rt)return 0;
int mid=(l+r)/2;
if(l==r)
{
return l;
}
if(k<=tree[tree[rt].lson].val-tree[tree[ort].lson].val)
{
return query(tree[rt].lson,tree[ort].lson,l,mid,k);
}else
{
k-=tree[tree[rt].lson].val-tree[tree[ort].lson].val;
return query(tree[rt].rson,tree[ort].rson,mid+1,r,k);
}
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++)
{
scanf("%d",&ed[i].v);
ed[i].po=i;
}
sort(ed+1,ed+1+n,cmp);
int tt=1;
ed2[ed[1].po].v=1;
ed2[ed[1].po].vy=ed[1].v;
for(int i = 2;i <= n;i++)
{
if(ed[i].v!=ed[i-1].v)
{
ed2[ed[i].po].v=++tt;
ed2[ed[i].po].vy=ed[i].v;
}else
{
ed2[ed[i].po].v=tt;
ed2[ed[i].po].vy=ed[i].v;
}
}
for(int i = 1;i <= n;i++)
{
insert(root[i],root[i-1],1,tt,ed2[i].v,1);
tval[ed2[i].v]=ed2[i].vy;
}
for(int i = 1;i <= m;i++)
{
int a,b,kk;
scanf("%d%d%d",&a,&b,&kk);
int ty=query(root[b],root[a-1],1,tt,kk);
printf("%d\n",tval[ty]);
}
return 0;
}