POJ K-th Number

【题解】

        数据结构采用线段树。通过将数组的每一段归并排序来建树。将数组排序来实现离散化。

        时间复杂度分析:建树的过程就是归并排序,其时间复杂度为O(nlog(n))。查询时:二分查找第k小元素的复杂度为O(log(n)),访问一个节点的复杂度为O(log(n))。因此,查询一次的复杂度为O((logn)^3),总复杂度为O(m(logn)^3)。

        空间复杂度:O(n)。

【代码】

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <algorithm>
 4 #include <vector>
 5 #define MID(x, y) ((x + y) >> 1)
 6 #define lson(x) (x << 1)
 7 #define rson(x) ((x << 1) | 1)
 8 
 9 using namespace std;
10 
11 const int maxn = 100010;
12 const int maxm = 50005;
13 
14 int a[maxn << 4];
15 vector<int> tree[maxm << 4];
16 
17 void build(int root, int L, int R)
18 {
19     if (L == R) {
20         tree[root].push_back(a[L]);
21         return;
22     }
23     build(lson(root), L, MID(L, R)), build(rson(root), MID(L, R) + 1, R);
24     tree[root].resize(R - L + 1);
25     merge(tree[lson(root)].begin(), tree[lson(root)].end(), tree[rson(root)].begin(), tree[rson(root)].end(), tree[root].begin());
26 }    
27 
28 int query(int root, int l, int r, int L, int R, int x)
29 {
30     if (r < L || l > R)return 0;
31     if (L <= l && r <= R) {
32         return upper_bound(tree[root].begin(), tree[root].end(), x) - tree[root].begin();
33     }
34     else {
35         int re1 = 0, re2 = 0;
36         re1 = query(lson(root), l, MID(l, r), L, R, x);
37         re2 = query(rson(root), MID(l, r) + 1, r, L, R, x);
38         return re1 + re2;
39     }
40 }
41 
42 int main()
43 {
44     int array_size, quest_n, i = 0, j, k, l, r , mid, ans;
45     scanf("%d %d", &array_size, &quest_n);
46     for (i = 1; i <= array_size; i++) scanf("%d", &a[i]);
47     build(1, 1, array_size);
48     sort(a + 1, a + array_size + 1);
49     while (quest_n--) {
50         scanf("%d %d %d", &i, &j, &k);
51         l = 1, r = array_size;
52         mid = 0, ans = 0;
53         while (l <= r) {
54             mid = MID(l, r);
55             if (query(1, 1, array_size, i, j, a[mid]) >= k) {
56                 ans = mid;
57                 r = mid - 1;
58             }
59             else l = mid + 1;
60         }
61         printf("%d\n", a[ans]);
62     }
63     return 0;
64 }

猜你喜欢

转载自www.cnblogs.com/Jeffrey-Y/p/9858189.html