zoukankan      html  css  js  c++  java
  • Poj 2104区间第k大(归并树)

    题目链接

    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
    ", a[ub]);
    66         }
    67     }
    68 
    69     return 0;
    70 }
  • 相关阅读:
    Nginx有哪些作用?
    MYSQL如何优化?
    jdk1.8新特性
    [javase基础] JDK JRE JVM的区别?
    JDBC中如何进行事务处理?
    JDBC、ibatis(mybatis)、Hibernate有什么不同?
    java面试题最容易犯错
    Spring高频率面试题
    python pip whl安装和使用
    深入理解 Linux的进程,线程,PID,LWP,TID,TGID
  • 原文地址:https://www.cnblogs.com/Stomach-ache/p/3887394.html
Copyright © 2011-2022 走看看