记录编号 |
144581 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[河南省队2012] 找第k小的数 |
最终得分 |
100 |
用户昵称 |
天一阁 |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
1.432 s |
提交时间 |
2014-12-24 11:41:07 |
内存使用 |
91.87 MiB |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define l(x) ch[x][0]
#define r(x) ch[x][1]
#define Maxn 4000010
using namespace std;
int n,m,N=1,root[Maxn],tot=0;
int ch[Maxn][2],sumt[Maxn]={0};
int a[Maxn],a0[Maxn];
int build(int l,int r){
int x=++tot;
if(l<r){
int mid=(l+r)>>1;
l(x)=build(l,mid);
r(x)=build(mid+1,r);
}
return x;
}
void Print(int x[],int len){
for(int i=1;i<=len;i++) cout<<x[i]<<' ';
cout<<endl;
}
int change(int o,int l,int r,int qx,int v){
int x=++tot; sumt[x]=sumt[o]+v;
l(x)=l(o); r(x)=r(o);
if(l<r){
int mid=(l+r)>>1;
if(qx<=mid) l(x)=change(l(o),l,mid,qx,v);
else r(x)=change(r(o),mid+1,r,qx,v);
}
return x;
}
int query(int o1,int o2,int l,int r,int k){
if(l==r) return l;
else{
int mid=(l+r)>>1;
int t=sumt[l(o1)]-sumt[l(o2)];
if(t>=k) return query(l(o1),l(o2),l,mid,k);
else return query(r(o1),r(o2),mid+1,r,k-t);
}
}
void maketree(){
root[0]=build(1,N);
for(int i=1;i<=n;i++) root[i]=change(root[i-1],1,N,a[i],1);
}
void work(){
int x,y,k;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&k);
printf("%d\n",a0[query(root[y],root[x-1],1,N,k)]);
}
}
void init(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),a0[i]=a[i];
sort(a0+1,a0+n+1);
for(int i=2;i<=n;i++) if(a0[i]!=a0[i-1]) a0[++N]=a0[i];
for(int i=1;i<=n;i++) a[i]=lower_bound(a0+1,a0+N+1,a[i])-a0;
}
int main(){
freopen("kth.in","r",stdin);
freopen("kth.out","w",stdout);
init();
maketree();
work();
return 0;
}