题目链接
题目大意
给你n个数字,m次查询,每次查询区间第k大的数是多少。
解题思路
主席树的模板题
注意离散化。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1e5+5;
struct node
{
int l,r,sum;
};
node e[N*20];
int a[N],b[N],c[N],root[N],cnt;
void init()
{
cnt=1;
memset(root,0,sizeof(root));
e[0].sum=e[0].l=e[0].r=0;
}
void update(int num,int &rt,int l,int r)
{
e[cnt++]=e[rt];
rt=cnt-1;
e[rt].sum++;
if(l==r)
return ;
int mid=(l+r)/2;
if(num<=mid)
update(num,e[rt].l,l,mid);
else
update(num,e[rt].r,mid+1,r);
}
int que(int i,int j,int k,int l,int r)
{
int d=e[e[j].l].sum-e[e[i].l].sum;
if(l==r)
return l;
int mid=(l+r)/2;
if(k<=d)
return que(e[i].l,e[j].l,k,l,mid);
else
return que(e[i].r,e[j].r,k-d,mid+1,r);
}
int main()
{
init();
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
int ans=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++)
{
int aa=lower_bound(b+1,b+1+n,a[i])-b;
root[i]=root[i-1];
update(aa,root[i],1,ans);
}
int x,y,z;
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&x,&y,&z);
printf("%d\n",b[que(root[x-1],root[y],z,1,n)]);
}
return 0;
}