Question: n numbers are given, and m queries are made. The k-th digit in the [a, B] of each query interval is output. A Data Structure is used to divide the tree. Tree Division means that each node stores all the elements in the [l, r] interval. The order of elements is the same as that of the original array, however, the elements of the two subtree are the first (r-l + 1)/Two (r-l + 1) After all the elements of the node are sorted to the left subtree, and the remaining to the right subtree, at the same time, a sum field is maintained. sum [I] indicates how many of the vertices l -- I have entered the left subtree. For query, In the range [l, r], find the k-th large number, t is the node, and tree [t]. l, tree [t]. r indicates the left and right intervals of the node. Mid is the range value. 1. sum [r]-sum [L-1]> = k, search for LL (t), and the interval corresponds to [tree [t]. l + sum [L-1], tree [t]. l + sum [r]-1] 2. sum [r]-sum L-1] <k, search for RR (t ), the interval corresponds to [mid + 1 + l-tree [t]. l-sum [L-1], mid + 1 + r-tree [t]. l-sum [r] For details, see the code [cpp] # include <iostream> # include <cstdio> # include <algorithm> # include <string> # include <cmath> # include <cstring> # include <queue> # include <set> # include <vector> # include <stack> # include <map> # include <iomanip> # define P I acos (-1.0) # define Max 100005 # define inf 1 <28 # define LL (x) (x <1) # define RR (x) (x <1 | 1) # define FOR (I, s, t) for (int I = (s); I <= (t); ++ I) # define ll long # define mem (a, B) memset (a, B, sizeof (a) # define mp (a, B) make_pair (a, B) using namespace std; int lessmid [20] [Max]; // number of values smaller than the mid value in the interval. Int seg [20] [Max]; int num [Max]; struct seg_tree {int l, r;} tree [Max * 4]; void build_tree (int l, int r, int u, int d) {tree [u]. l = l, tree [u]. r = r; if (l = r) return; int mid = l + r> 1; int issame = mid-l + 1; // The total number of elements on the left side of the for (int I = l; I <= r; I ++) if (seg [d] [I] <num [mid]) // if all the values smaller than the center value are placed on the issame --; // issame -- on the left, this value can be placed on the left, and the total number on the left is reduced. // The total number of issame is the number of digits that are equal to or equal to the value. Int lpos = l, rpos = mid + 1; for (int I = l; I <= r; I ++) {if (I = l) lessmid [d] [I] = 0; // The number of lessmid [d] [I] records less than or equal to the number of values in layer d and between [l, I. Else lessmid [d] [I] = lessmid [d] [I-1]; if (seg [d] [I] <num [mid]) {lessmid [d] [I] ++; // less than the median value. The count is added with seg [d + 1] [lpos ++] = seg [d] [I]; // put this number to the left} else if (seg [d] [I]> num [mid]) {seg [d + 1] [rpos ++] = seg [d] [I]; // similarly} else // if they are equal, the issame element above is required. {if (issame> 0) // if issame> 0, the left side is not filled, and the number equal to the value can be left. {Issame --; lessmid [d] [I] ++; // here, the number is equal to the number of values. Seg [d + 1] [lpos ++] = seg [d] [I];} else seg [d + 1] [rpos ++] = seg [d] [I] ;}} build_tree (l, mid, LL (u), d + 1 ); build_tree (mid + 1, r, RR (u), d + 1);} int update (int l, int r, int u, int d, int cnt) {if (l = r) return seg [d] [l]; int num1, num2; if (l = tree [u]. l) {num1 = lessmid [d] [r]; num2 = 0;} else {num1 = lessmid [d] [r]-lessmid [d L-1]; // put the number of values smaller than or equal to the value of [l, r] on the left num2 = lessmid [d] L-1]; // [tree [u]. l L-1] is less than or equal to the number of values, placed in Left} if (num1> = cnt) {return update (tree [u]. l + num2, tree [u]. l + num1 + num2-1, LL (u), d + 1, cnt);} else {int mid = tree [u]. l + tree [u]. r> 1; int num4 = l-tree [u]. l-num2; // [tree [u]. l, l-1] The total number to the right. Int num3 = r-l + 1-num1; // the total number of places [l, r] on the right. Return update (mid + num4 + 1, mid + num3 + num4, RR (u), d + 1, cnt-num1) ;}} int main () {int n, m; cin> n> m; for (int I = 1; I <= n; I ++) {scanf ("% d ", & num [I]); seg [1] [I] = num [I];} sort (num + 1, num + n + 1); build_tree (1, n, 1, 1); while (m --) {int a, B, c; scanf ("% d", & a, & B, & c ); printf ("% d \ n", update (a, B, 1, 1, c);} return 0 ;}