Kth numberTime Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission (s): 4585 Accepted Submission (s): 1461
Problem DescriptionGive you a sequence and ask you the kth big number of a inteval.
InputThe first line is the number of the test cases.
For each test case, the first line contain two integer n and m (n, m <= 100000), indicates the number of integers in the sequence and the number of the quaere.
The second line contains n integers, describe the sequence.
Each of following m lines contains three integers s, t, k.
[S, t] indicates the interval and k indicates the kth big number in interval [s, t]
OutputFor each test case, output m lines. Each line contains the kth big number.
Sample Input
1 10 1 1 4 2 3 5 6 7 8 9 0 1 3 2
Sample Output
2
SourceHDU boys' open session-From WHU)
Recommendzty | We have carefully selected several similar problems for you: 2660 2662 2667 2663
When I started to use the merging Tree, I had to learn to divide the tree = Mom, and I had to read it for a long time.
The principle of building a tree is a bit similar to that of a merged tree, except that the tree uses a fast sorting method. First, the original series are sorted, and the building is based on a large number in the middle, you can throw a small one to the left and a large one to the right. There are some small details. If there are multiple numbers that are the same as the base number, you need to record a temporary variable, use seg [dep] [I] to record the number of I-to-left intervals which is smaller than the base number. When querying, you can determine whether the interval has
# Include
# Include
# Include
# Include
# Include
# Include
Using namespace std; const int maxn = 100000 + 10; struct node {int lson, rson; int mid () {return (lson + rson)> 1 ;}} tree [maxn * 4]; int seg [25] [maxn]; int lftnum [25] [maxn]; int num [maxn]; int n, m, sta, ed; void build (int L, int R, int rt, int dep) {tree [rt]. lson = L; tree [rt]. rson = R; if (L = R) return; int mid = tree [rt]. mid (), key = num [mid], scnt = mid-L + 1; // The number of center values on the left for (int I = L; I <= R; I ++) {if (seg [dep] [I] <num [mid]) {scnt -- ;}} int lp = L, rp = mid + 1; for (int I = L; I <= R; I ++) {if (I = L) {lftnum [dep] [I] = 0 ;} else {lftnum [dep] [I] = lftnum [dep] [I-1];} if (seg [dep] [I] <key) {lftnum [dep] [I] ++; seg [dep + 1] [lp ++] = seg [dep] [I];} else if (seg [dep] [I]> key) {seg [dep + 1] [rp ++] = seg [dep] [I];} else {if (scnt> 0) {scnt --; lftnum [dep] [I] ++; seg [dep + 1] [lp ++] = seg [dep] [I];} else {seg [dep + 1] [rp ++] = seg [dep] [I] ;}} build (L, mid, rt <1, dep + 1); build (mid + 1, R, rt <1 | 1, dep + 1);} int query (int L, int R, int rt, int dep, int k) {if (tree [rt]. lson = tree [rt]. rson) {return seg [dep] [L];} int cnt, act; if (L = tree [rt]. lson) {cnt = lftnum [dep] [R]; act = 0;} else {cnt = lftnum [dep] [R]-lftnum [dep] [L-1]; act = lftnum [dep] [L-1];} int mid = tree [rt]. mid (); if (cnt> = k) {L = tree [rt]. lson + act; R = tree [rt]. lson + act + cnt-1; return query (L, R, rt <1, dep + 1, k);} else {int a = L-tree [rt]. lson-act; int B = R-L-cnt + 1; L = mid + a + 1; R = mid + a + B; return query (L, R, rt <1 | 1, dep + 1, k-cnt) ;}int main () {int ncase; cin> ncase; while (ncase --) {cin> n> m; for (int I = 1; I <= n; I ++) {scanf ("% d", & num [I]); seg [0] [I] = num [I];} sort (num + 1, num + n + 1); build (1, n, 1, 0 ); while (m --) {int k; scanf ("% d", & sta, & ed, & k); printf ("% d \ n ", query (sta, ed, 1, 0, k) ;}} return 0 ;}