Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4417
Question: calculate the number of numbers not greater than h in any range of a series.
Idea: This question can be done with the Division tree, we just need to find the smallest number in the range greater than H, if it is the K number in the range, then the answer is the K-1, we can search for the nth decimal number of the range by means of binary, and find the smallest number greater than h to get the answer. Note that h may be larger than all the books in the range, this requires special processing. The following code is used:
# Include <iostream> # include <string. h> # include <stdio. h >#include <algorithm> # define maxn 100010 # define mid (L + r)> 1) Using namespace STD; int T [20] [maxn], sum [20] [maxn]; int as [maxn]; // The following is the void build (int p, int L, int R) of the K Division tree in the search interval) {int LM = 0, I, ls = L, RS = Mid + 1; for (I = mid; I> = L; I --) {if (as [I] = as [Mid]) lm ++; else break;} for (I = L; I <= r; I ++) {if (I = L) sum [p] [I] = 0; else sum [p] [I] = sum [p] [I-1]; if (T [p] [I] = as [Mid]) {If (LM) {lm --; sum [p] [I] ++; T [p + 1] [ls ++] = T [p] [I];} else t [p + 1] [RS ++] = T [p] [I];} else if (T [p] [I] <as [Mid]) // The maximum K value in the search interval is> {sum [p] [I] ++; T [p + 1] [ls ++] = T [p] [I];} else t [p + 1] [RS ++] = T [p] [I];} If (L = r) return; build (p + 1, l, mid); Build (p + 1, Mid + 1, R);} int query (int p, int L, int R, int Ql, int QR, int K) {int S, SS; If (L = r) return T [p] [l]; If (QL = L) S = 0, ss = sum [p] [QR]; else S = sum [p] [ql-1], Ss = sum [p] [QR]-S; If (k <= SS) return query (p + 1, L, mid, L + S, L + sum [p] [QR]-1, k); else return query (p + 1, mid + 1, R, Mid + 1-L + QL-S, Mid + 1-L + QR-sum [p] [QR], K-SS);} int main () {freopen ("dd.txt", "r", stdin); int ncase; scanf ("% d", & ncase); int time = 0; while (ncase --) {printf ("case % d: \ n", ++ time); int I, n, m; scanf ("% d", & N, & M ); for (I = 0; I <n; I ++) {scanf ("% d", & as [I]); T [0] [I] = as [I];} Sort (as, as + n); Build (, n-1); While (M --) {int l, r, K; scanf ("% d", & L, & R, & K); int MI = 1, MA = r-L + 1, mid, ans = r-L + 2; while (MI <= MA) {mid = (MI + Ma)> 1; int TMP = query (0,0, n-1, L, R, mid); If (TMP> K) {ans = mid; MA = mid-1;} else MI = Mid + 1;} printf ("% d \ n ", ans-1);} return 0 ;}