您的位置:首页 > 其它

POJ 2104 K-th Number 不高效的线段树写法

2014-04-07 22:42 211 查看
区间k大数问题

const int Max_N = 100008  ;

int  A[Max_N] ;
vector<int> data[Max_N<<2] ;

void  make_tree(int L , int R , int root){
if(L == R){
data[root].clear() ;
data[root].push_back(A[L]) ;
return  ;
}
int mid = (L + R) >> 1 ;
make_tree(L , mid , root<<1) ;
make_tree(mid+1 , R ,root<<1|1) ;
data[root].resize(R-L+1) ;
merge(data[root<<1].begin() , data[root<<1].end() ,
data[root<<1|1].begin() , data[root<<1|1].end() , data[root].begin()) ;
}

int query(int l , int r  , int x , int L , int R , int root){
if(r < L || l > R)  return 0 ;
if(l <= L && R <= r)
return upper_bound(data[root].begin() , data[root].end() , x) - data[root].begin() ;
int mid = (L + R) >> 1 ;
return query(l , r , x , L , mid , root<<1)
+ query(l , r , x , mid+1 , R , root<<1|1) ;
}

int  main(){
int T , N , i , M , l , r , k  , L , R , mid , ans ;
cin>>N>>M;
for(i = 1 ; i <= N ; i++)
scanf("%d" ,&A[i]) ;
make_tree(1 , N , 1) ;
sort(A+1 , A+1+N) ;
while(M--){
scanf("%d%d%d" ,&l ,&r ,&k) ;
L = 1 ;
R = N ;
while(L <= R){
mid = (L + R) >> 1 ;
if(query(l , r , A[mid] , 1 , N , 1) >= k){
R = mid - 1 ;
ans = A[mid] ;
}
else
L = mid + 1 ;
}
printf("%d\n" ,ans) ;
}
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: