推荐这位大牛的博文,讲得很清晰易懂: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 }
实现代码: