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 }

实现代码:

原文地址:https://www.cnblogs.com/Onlynagesha/p/8796505.html