记录编号 327784 评测结果 AAAAAAAAAA
题目名称 [河南省队2012] 找第k小的数 最终得分 100
用户昵称 GravatarAntiLeaf 是否通过 通过
代码语言 C++ 运行时间 3.304 s
提交时间 2016-10-22 21:39:37 内存使用 44.90 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100010;
void build(int,int,int&,int);
int query(int,int,int,int);
int sm[maxn<<5]={0},lc[maxn<<5]={0},rc[maxn<<5]={0},root[maxn<<5]={0},cnt=0;
int n,m,a[maxn],b[maxn],x,l,r,k;
int main(){
#define MINE
#ifdef MINE
	freopen("kth.in","r",stdin);
	freopen("kth.out","w",stdout);
#endif
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	copy(a+1,a+n+1,b+1);
	sort(b+1,b+n+1);
	for(int i=1;i<=n;i++){
		x=lower_bound(b+1,b+n+1,a[i])-b;
		build(1,n,root[i],root[i-1]);
	}
	while(m--){
		scanf("%d%d%d",&l,&r,&k);
		printf("%d\n",query(1,n,root[r],root[l-1]));
	}
#ifndef MINE
	printf("\n-------------------------DONE-------------------------\n");
	for(;;);
#endif
	return 0;
}
void build(int l,int r,int &rt,int pr){
	sm[rt=++cnt]=sm[pr]+1;
	if(l==r)return;
	lc[rt]=lc[pr];rc[rt]=rc[pr];
	int mid=(l+r)>>1;
	if(x<=mid)build(l,mid,lc[rt],lc[pr]);
	else build(mid+1,r,rc[rt],rc[pr]);
}
int query(int l,int r,int rt,int pr){
	if(l==r)return b[l];
	int mid=(l+r)>>1;
	if(k<=sm[lc[rt]]-sm[lc[pr]])return query(l,mid,lc[rt],lc[pr]);
	else{
		k-=sm[lc[rt]]-sm[lc[pr]];
		return query(mid+1,r,rc[rt],rc[pr]);
	}
}