Question: There are n numbers, M queries (L, R, K), and the number of [L, R] In the interval is less than or equal to K.
Split tree -- search for the number of K in the range ....
Based on the nature of the decision tree, the number of [L, R] In the interval is less than or equal to K.
If the number TMP> K is larger than I in the range, search for it. If TMP <K, search for it.
# Include <cstdio> # include <stdlib. h> # include <string. h> # include <string> # include <map> # include <cmath> # include <iostream> # include <queue> # include <stack> # include <algorithm> # include <set> using namespace STD; # define INF 1e8 # define EPS 1e-8 # define ll long # define n 100010 # define mod 1000000007 int A [n], s [N], t [20] [N], num [20] [N], n, m; void build (int c, int L, int R) {If (L = r) return; int mid = (L + r)/2; int LM = mid-L + 1, Lp = L, Rp = Mid + 1; for (INT I = L; I <= r; I ++) lm-= s [I] <s [Mid]; for (INT I = L; I <= r; I ++) {if (I = L) num [C] [I] = 0; else num [C] [I] = num [C] [I-1]; if (T [C] [I] = s [Mid]) {If (LM) {lm --; num [C] [I] ++; T [C + 1] [LP ++] = T [C] [I];} else t [C + 1] [RP ++] = T [C] [I];} else if (T [C] [I] <s [Mid]) {num [C] [I] ++; t [C + 1] [LP ++] = T [C] [I];} else t [C + 1] [RP ++] = T [C] [I];} build (C + 1, L, mid); Build (C + 1, mid + 1, R);} int query (int c, int L, int R, int Ql, int QR, int K) {If (L = r) return T [C] [l]; int S, SS, mid = (L + r)/2; If (QL = L) S = 0, ss = num [C] [QR]; else S = num [C] [ql-1], Ss = num [C] [QR]-num [C] [ql-1]; if (k <= SS) return query (C + 1, L, mid, L + S, S + L + ss-1, k); else return query (C + 1, mid + 1, R, Mid + 1 + QL-l-S, Mid + 1 + QR-l-S-SS, K-SS);} int main () {int T, CA = 1; scanf ("% d", & T); While (t --) {scanf ("% d", & N, & M); For (INT I = 1; I <= N; I ++) {scanf ("% d", & A [I]); s [I] = T [0] [I] = A [I];} Sort (S + 1, S + n + 1); Build (0, 1, n ); printf ("case % d: \ n", CA ++); While (M --) {int L, R, K; scanf ("% d ", & L, & R, & K); L ++; r ++; If (query (0, 1, n, l, R, R-l + 1) <= K) printf ("% d \ n", R-l + 1); else if (query (0, 1, n, l, R, 1)> K) puts ("0"); else {int LL = 0, RR = r-L + 1, mid; while (LL <= RR) {mid = (LL + RR)> 1; int TMP = query (0, 1, n, l, R, mid); // if the range is [L, r] The number of mid is greater than K, RR = mid-1if (TMP> K) RR = mid-1; else LL = Mid + 1; // otherwise LL = Mid + 1} printf ("% d \ n", ll-1) ;}}} return 0 ;} /* 110 100 5 2 7 5 4 3 8 7 7 2 8 63 5 01 3 11 9 40 1 03 5 5 5 14 6 31 5 75 7 3 */