码迷,mamicode.com
首页 > 其他好文 > 详细

数据结构2 静态区间第K大/第K小

时间:2016-08-01 00:06:51      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:

给定数组$A[1...N]$, 区间$[L,R]$中第$K$大/小的数的指将$A[L...R]$中的数从大到小/从小到大排序后的第$K$个.

"静态"指的是不带修改.

这个问题有多种做法:

1. 归并排序

POJ 2104, 静态区间第K小

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N(1e5+5);
 5 int a[18][N];
 6 
 7 void merge(int id, int b, int e){
 8     int mid=(b+e)>>1;
 9     for(int l=b, r=mid, i=b; i<e; i++){
10         if(l==mid) a[id][i]=a[id+1][r++];
11         else if(r==e) a[id][i]=a[id+1][l++];
12         else if(a[id+1][l]<=a[id+1][r]) a[id][i]=a[id+1][l++];
13         else a[id][i]=a[id+1][r++]; 
14     }
15 }
16 
17 void build(int id, int b, int e){
18     if(b+1==e){
19         scanf("%d", a[id]+b);
20         return;
21     }
22     int mid=(b+e)>>1;
23     build(id+1, b, mid);
24     build(id+1, mid, e);
25     merge(id, b, e);
26 }
27 //返回k在[l, r)与[L, R)交集上的Rank
28 int Rank(int id, int L, int R, int l, int r, int k){
29     if(l<=L&&R<=r){
30         return lower_bound(a[id]+L, a[id]+R, k)-a[id]-L;
31     }
32     int mid=(L+R)>>1;
33     if(r<=mid){
34         return Rank(id+1, L, mid, l, r, k);
35     }
36     if(l>=mid){
37         return Rank(id+1, mid, R, l, r, k);
38     }
39     return Rank(id+1, L, mid, l, r, k)+Rank(id+1, mid, R, l, r, k);
40 }
41 //返回(l, r]中Rank(x)>=k的最小的x
42 int BS(int b, int e, int k, int n){
43     int l=-1e9-1, r=1e9+1, mid;
44     while(r-l>1){
45         mid=(l+r)>>1;
46         if(Rank(0, 0, n, b, e, mid)>=k) r=mid;
47         else l=mid;
48     }
49     return r;
50 }
51 int main(){
52     int n, m; scanf("%d%d", &n, &m);
53     build(0, 0, n);
54     for(int l, r, k; m--;){
55         scanf("%d%d%d", &l, &r, &k), l--;
56         printf("%d\n", BS(l, r, k, n)-1);
57     }
58 }

 归并排序解决这个问题的想法是将归并排序的过程记录下来, 这样就形成了一棵线段树, 这棵线段树的每个节点记录着它所代表的那个区间[L,R]排好序后的情形.

我们把这样的线段树称做归并树, 归并树能在$O(\log^2{N})$的复杂度内完成如下查询:

$\text{RANK}(l, r, x)$: 区间$[l,r]$内小于$x$的数的数目.

定义$\text{LEAST}(l, r, k)$为区间$[l,r]$上第$k$小的数, 则有

$\text{LEAST}(l, r, k) = \max \{x \mid \text{RANK}(l, r, x)<k\}$

 

数据结构2 静态区间第K大/第K小

标签:

原文地址:http://www.cnblogs.com/Patt/p/5724316.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!