• POJ 2104, SPOJ MKTHNUM


    推荐这位大牛的博文,讲得很清晰易懂:http://www.cnblogs.com/zinthos/p/3899565.html

    节点个数很多时似乎用new动态开内存的方法会显著变慢,节点个数较少时倒没啥感觉。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 
      5 const int maxN = (int)1e5 + 10;
      6 
      7 int A[maxN], AProj[maxN], mapped[maxN];
      8 int N, K;
      9 
     10 void input()
     11 {
     12     scanf("%d%d", &N, &K);
     13     for (int i = 1; i <= N; i++)
     14         scanf("%d", A + i);
     15 
     16     memcpy(mapped + 1, A + 1, sizeof(int) * N);
     17     std::sort(mapped + 1, mapped + N + 1);
     18 
     19     for (int i = 1; i <= N; i++)
     20         AProj[i] = int(std::lower_bound(mapped + 1, mapped + N + 1, A[i]) - mapped);
     21 }
     22 
     23 struct Node
     24 {
     25     int cnt;
     26     int ch[2];
     27 };
     28 Node node[maxN * 20];
     29 int root[maxN];
     30 int cnt = 0;
     31 
     32 inline int newNode() { return cnt++; }
     33 
     34 int _init0(int l, int r)
     35 {
     36     if (l + 1 == r)
     37         return newNode();
     38 
     39     int res = newNode();
     40     int m = (l + r) >> 1;
     41     node[res].ch[0] = _init0(l, m);
     42     node[res].ch[1] = _init0(m, r);
     43 
     44     return res;
     45 }
     46 
     47 int insert(int val, int prev)
     48 {
     49     int l = 1, r = N + 1;
     50     int res = newNode();
     51     int cur = res;
     52 
     53     while (true)
     54     {
     55         node[cur] = node[prev];
     56         node[cur].cnt += 1;
     57 
     58         if (l + 1 == r)
     59             break;
     60 
     61         int m = (l + r) >> 1;
     62         int dir = (val < m ? 0 : 1);
     63         val < m ? r = m : l = m;
     64 
     65         cur = node[cur].ch[dir] = newNode();
     66         prev = node[prev].ch[dir];
     67     }
     68 
     69     return res;
     70 }
     71 
     72 void build()
     73 {
     74     root[0] = _init0(1, N + 1);
     75     for (int i = 1; i <= N; i++)
     76         root[i] = insert(AProj[i], root[i - 1]);
     77 }
     78 
     79 int query(int l, int r, int k) //[l, r]
     80 {
     81     int pl = root[l - 1], pr = root[r];
     82     int nl = 1, nr = N + 1;
     83 
     84     while (nl + 1 < nr)
     85     {
     86         int ls = node[node[pr].ch[0]].cnt - node[node[pl].ch[0]].cnt;
     87         int mid = (nl + nr) >> 1;
     88         int dir = (ls < k ? 1 : 0);
     89 
     90         if (ls < k)
     91             k -= ls;
     92         dir == 0 ? nr = mid : nl = mid;
     93         pl = node[pl].ch[dir];
     94         pr = node[pr].ch[dir];
     95     }
     96 
     97     return nl;
     98 }
     99 
    100 int main()
    101 {
    102     input();
    103     build();
    104 
    105     for (int l, r, k, i = 1; i <= K; i++)
    106     {
    107         scanf("%d%d%d", &l, &r, &k);
    108         printf("%d
    ", mapped[query(l, r, k)]);
    109     }
    110     return 0;
    111 }

    实现代码:

  • 相关阅读:
    2019.8.6原型链与继承
    2019.8.2闭包,作用域
    2019.8.1正则二
    2019.7.31正则
    2019.7.29二维数组
    2019.7.28关于数组和循环的八道题
    2019.7.27数组api
    DOM
    JavaScript数组5种去重方法
    JavaScript面向对象
  • 原文地址:https://www.cnblogs.com/Onlynagesha/p/8796505.html
Copyright © 2020-2023  润新知