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

Poj 2104区间第k大(归并树)

时间:2014-08-02 20:46:54      阅读:260      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   使用   os   strong   

题目链接

K-th Number
Time Limit: 20000MS Memory Limit: 65536K
Total Submissions: 36890 Accepted: 11860
Case Time Limit: 2000MS

Description

You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array segment. 
That is, given an array a[1...n] of different integer numbers, your program must answer a series of questions Q(i, j, k) in the form: "What would be the k-th number in a[i...j] segment, if this segment was sorted?" 
For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the question be Q(2, 5, 3). The segment a[2...5] is (5, 2, 6, 3). If we sort this segment, we get (2, 3, 5, 6), the third number is 5, and therefore the answer to the question is 5.

Input

The first line of the input file contains n --- the size of the array, and m --- the number of questions to answer (1 <= n <= 100 000, 1 <= m <= 5 000). 
The second line contains n different integer numbers not exceeding 109 by their absolute values --- the array for which the answers should be given. 
The following m lines contain question descriptions, each description consists of three numbers: i, j, and k (1 <= i <= j <= n, 1 <= k <= j - i + 1) and represents the question Q(i, j, k).

Output

For each question output the answer to it --- the k-th number in sorted a[i...j] segment.

Sample Input

7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3

Sample Output

5
6
3

Hint

This problem has huge input,so please use c-style input(scanf,printf),or you may got time limit exceed.
题意很简单,给定长度为n的数组,有m次查询,每次长须L到R中第k大的数。
很早便想A掉这道题,开始用平方分割写的这题,妥妥的TLE. 后来知道这类题目应该
使用归并树,或者划分树,或是更高级的主席树,刚刚对归并树有一点了解,便来1A了他。
做法就是:如果x是某个区间的第k大数,那么区间内不超过x的数不小于k个。
而且区间内小于x的数不足k个。
二分x, 查询区间内不大于x的数的个数。
Accepted Code:
 1 /*************************************************************************
 2     > File Name: 2104.cpp
 3     > Author: Stomach_ache
 4     > Mail: sudaweitong@gmail.com
 5     > Created Time: 2014年08月02日 星期六 19时25分26秒
 6     > Propose: 
 7  ************************************************************************/
 8 
 9 #include <cmath>
10 #include <string>
11 #include <cstdio>
12 #include <vector>
13 #include <fstream>
14 #include <cstring>
15 #include <iostream>
16 #include <algorithm>
17 using namespace std;
18 
19 #define lson(x) (x<<1)
20 #define rson(x) ((x<<1)|1)
21 const int maxn = 100002;
22 int n, m;
23 int a[maxn], nums[maxn];
24 vector<int> dat[maxn<<2];
25 
26 void build(int o, int l, int r) {
27       if (r - l == 1) {
28           dat[o].push_back(a[l]);
29     } else {
30           int mid = (l + r) / 2;
31           build(lson(o), l, mid);
32         build(rson(o), mid, r);
33         dat[o].resize(r-l);
34         merge(dat[lson(o)].begin(), dat[lson(o)].end(), dat[rson(o)].begin(), dat[rson(o)].end(), dat[o].begin());
35     }
36 }
37 
38 int query(int L, int R, int x, int o, int l, int r) {
39       if (l >= R || r <= L) return 0;
40     else if (l >= L && r <= R) return upper_bound(dat[o].begin(), dat[o].end(), x) - dat[o].begin();
41     else {
42           int md = (l + r) / 2;
43           int lc = query(L, R, x, lson(o), l, md);
44         int rc = query(L, R, x, rson(o), md, r);
45         return lc + rc;
46     }
47 }
48 
49 int main(void) {
50       while (~scanf("%d %d", &n, &m)) {
51           for (int i = 0; i < n; i++) scanf("%d", a + i);
52         build(1, 0, n);
53         sort(a, a + n);
54         while (m--) {
55               int l, r, k;
56             scanf("%d %d %d", &l, &r, &k);
57             l--; r--;
58             int lb = -1, ub = n-1;
59             while (ub - lb > 1) {
60                   int md = (lb + ub) / 2;
61                 int c = query(l, r+1, a[md], 1, 0, n);
62                 if (c >= k) ub = md;
63                 else lb = md;
64             }
65             printf("%d\n", a[ub]);
66         }
67     }
68 
69     return 0;
70 }

 

Poj 2104区间第k大(归并树),布布扣,bubuko.com

Poj 2104区间第k大(归并树)

标签:des   style   blog   http   color   使用   os   strong   

原文地址:http://www.cnblogs.com/Stomach-ache/p/3887394.html

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