记录编号 144419 评测结果 AAAAAAAAAA
题目名称 [河南省队2012] 找第k小的数 最终得分 100
用户昵称 Gravatarztx 是否通过 通过
代码语言 C++ 运行时间 1.415 s
提交时间 2014-12-23 09:25:45 内存使用 65.14 MiB
显示代码纯文本
/****************************************\
* Author : hzoi_ztx
* Title  : [河南省队2012] 找第k小的数
* ALG    :
* CMT    :
* Time   :
\****************************************/

#include <cstdio>

int CH , NEG ;

inline void read(int& ret) {
    ret = NEG = 0 ; while (CH=getchar() , CH<'!') ;
    if (CH == '-') NEG = true , CH = getchar() ;
    while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ;
    if (NEG) ret = -ret ;
}

#include <algorithm>

#define  maxn  1000010LL
#define  maxt  4000000LL

struct num { int val , pos , tim ; } a[maxn] ;
bool CmpV(const num& a , const num& b) {
	if (a.val == b.val) return a.tim < b.tim ;
	return a.val < b.val ;
}
bool CmpT(const num& a , const num& b) {
	return a.tim < b.tim ;
}

int root[maxn] = {0} ;
int left[maxt] = {0} , right[maxt] = {0} , size[maxt] = {0} , tot = 0;
int leaf[maxn] = {0} ;

void Build(int root , int L , int R) {
	if (L == R) return ;
	left[root] = ++tot , right[root] = ++tot ;
	int M = L+(R-L)/2 ;
	Build(left[root] , L , M) ;
	Build(right[root] , M+1 , R) ;
}

void Insert(int root1 , int root2 , int L , int R , int pos) {
	size[root2] = size[root1]+1 ;
	if (L == R) return ;
	int M = L+(R-L)/2 ;
	if (pos > M) {
		left[root2] = left[root1] ;
		right[root2] = ++tot ;
		Insert(right[root1] , right[root2] , M+1 , R , pos ) ;
	} else {
		left[root2] = ++tot ;
		right[root2] = right[root1] ;
		Insert(left[root1] , left[root2] , L , M , pos) ;
	}
}

void Query(int root1 , int root2 , int L , int R , int k) {
	if (L == R) { printf("%d\n", leaf[L] ) ; return ; }
	int M = L+(R-L)/2 , tmpk = size[left[root2]]-size[left[root1]] ;
	if (k > tmpk) Query(right[root1] , right[root2] , M+1 , R , k-tmpk) ;
	else Query(left[root1] , left[root2] , L , M , k) ;
}

int n , m , i , j , k ;
int main() {
	#define READ
	#ifdef  READ
		freopen("kth.in" ,"r",stdin ) ;
		freopen("kth.out","w",stdout) ;
	#endif
	read(n) , read(m) ; root[0] = ++tot ;
	Build(root[0] , 1 , n) ;
	for (i = 1 ; i <= n ; i ++ ) read(a[i].val) , a[i].tim = i ;
	std::sort(a+1 , a+n+1 , CmpV) ;
	for (i = 1 ; i <= n ; i ++ ) a[i].pos = i , leaf[i] = a[i].val ;
	std::sort(a+1 , a+n+1 , CmpT) ;
	for (i = 1 ; i <= n ; i ++ ) root[i] = ++tot , Insert(root[i-1] , root[i] , 1 , n , a[i].pos) ;
	while ( m -- ) {
		read(i) , read(j) , read(k) ;
		Query(root[i-1] , root[j] , 1 , n , k) ;
	}
	#ifdef  READ
		fclose(stdin) ; fclose(stdout) ;
	#else
		getchar() ; getchar() ;
	#endif
	return 0 ;
}