zoukankan      html  css  js  c++  java
  • poj2104 K-th Number

    思路1:

    平方分割。

    实现:

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <vector>
     4 #include <cmath>
     5 using namespace std;
     6 const int MAXN = 100005;
     7 const int B = 1000;
     8 int n, m, a[MAXN], nums[MAXN];
     9 vector<int> v[MAXN / B];
    10 bool check(int x, int l, int r, int k)
    11 {
    12     int ans = 0;
    13     while (l < r && l % B) if (a[l++] <= nums[x]) ans++;
    14     while (r > l && r % B) if (a[--r] <= nums[x]) ans++;
    15     for (int i = l / B; i < r / B; i++)
    16     {
    17         ans += upper_bound(v[i].begin(), v[i].end(), nums[x]) - v[i].begin();
    18     }
    19     return ans >= k; 
    20 }
    21 int main()
    22 {
    23     scanf("%d %d", &n, &m);
    24     for (int i = 0; i < n; i++) 
    25     {
    26         scanf("%d", &a[i]);
    27         nums[i] = a[i];
    28         v[i / B].push_back(a[i]);
    29     }
    30     for (int i = 0; i <= n / B; i++) sort(v[i].begin(), v[i].end());
    31     sort(nums, nums + n);
    32     int x, y, k;
    33     for (int i = 0; i < m; i++)
    34     {
    35         scanf("%d %d %d", &x, &y, &k);
    36         x--;
    37         int l = 0, r = n - 1, ans = -1;
    38         while (l <= r)
    39         {
    40             int m = l + r >> 1;
    41             if (check(m, x, y, k)) { r = m - 1; ans = m; }
    42             else l = m + 1;
    43         }
    44         printf("%d
    ", nums[ans]);
    45     }
    46     return 0;
    47 }

     思路2:

    归并树。

    实现:

     1 #include <cstdio>
     2 #include <vector>
     3 #include <algorithm>
     4 using namespace std;
     5 const int MAXN = 100005;
     6 vector<int> tree[MAXN * 4], nums;
     7 int n, m, a[MAXN];
     8 
     9 void build(int num, int l, int r)
    10 {
    11     if (l == r) { tree[num].push_back(a[l]); return; }
    12     int m = l + r >> 1, lc = num * 2, rc = num * 2 + 1;
    13     build(lc, l, m);
    14     build(rc, m + 1, r);
    15     tree[num].resize(r - l + 1);
    16     merge(tree[lc].begin(), tree[lc].end(), tree[rc].begin(), tree[rc].end(), tree[num].begin());
    17 }
    18 
    19 int query(int x, int y, int d, int num, int l, int r)
    20 {
    21     if (y < l || x > r) return 0;
    22     if (x <= l && y >= r) return upper_bound(tree[num].begin(), tree[num].end(), d) - tree[num].begin();
    23     int m = l + r >> 1, ans = 0;
    24     if (x <= m) ans += query(x, y, d, num * 2, l, m);
    25     if (y >= m + 1) ans += query(x, y, d, num * 2 + 1, m + 1, r);
    26     return ans;
    27 }
    28 
    29 bool check(int x, int y, int d, int k)
    30 {
    31     int ans = query(x, y, nums[d], 1, 1, n);
    32     return ans >= k;
    33 }
    34 
    35 int main()
    36 {
    37     scanf("%d %d", &n, &m);
    38     nums.push_back(0);
    39     for (int i = 1; i <= n; i++) 
    40     {
    41         scanf("%d", &a[i]);
    42         nums.push_back(a[i]);
    43     }
    44     sort(nums.begin() + 1, nums.end());
    45     build(1, 1, n);    
    46     int x, y, k, ans = -1;
    47     for (int i = 0; i < m; i++)
    48     {
    49         scanf("%d %d %d", &x, &y, &k);
    50         int l = 1, r = n;
    51         while (l <= r)
    52         {
    53             int m = l + r >> 1;
    54             if (check(x, y, m, k)) r = m - 1, ans = m;
    55             else l = m + 1;
    56         }
    57         printf("%d
    ", nums[ans]);
    58     }
    59     return 0;
    60 }
  • 相关阅读:
    2019.4.18 淘宝商品显示块2号铺设练习
    Debuggee not connected 寒江孤钓<<windows 内核安全编程>> 学习笔记
    指定的服务已标记为删除 寒江孤钓<<windows 内核安全编程>> 学习笔记
    删除自定义服务 寒江孤钓<<windows 内核安全编程>> 学习笔记
    发生系统错误 1275.此驱动程序被阻止加载 寒江孤钓<<windows 内核安全编程>> 学习笔记
    无法编译出.sys文件 寒江孤钓<<windows 内核安全编程>> 学习笔记
    iOS11 适配
    curl
    ddd
    201060512 viewcontroller view
  • 原文地址:https://www.cnblogs.com/wangyiming/p/8453190.html
Copyright © 2011-2022 走看看