1 //Accepted 2665 703MS 16388K 2972 B G++
2 #include <stdio.h>
3 #include <algorithm>
4 using namespace std;
5 #define M 100001
6 #define LL(x) ((x)<<1)
7 #define RR(x) ((x)<<1|1)
8 struct Seg_Tree{
9 int left,right;
10 int mid() {
11 return (left + right) >> 1;
12 }
13 }tt[M*4];
14 int len;
15 int sorted[M];
16 int toLeft[20][M];
17 int val[20][M];
18
19 void build(int l,int r,int d,int idx) {
20 tt[idx].left = l;
21 tt[idx].right = r;
22 if(tt[idx].left == tt[idx].right) return ;
23 int mid = tt[idx].mid();
24 int lsame = mid - l + 1;//lsame表示和val_mid相等且分到左边的
25 for(int i = l ; i <= r ; i ++) {
26 if(val[d][i] < sorted[mid]) {
27 lsame --;//先假设左边的数(mid - l + 1)个都等于val_mid,然后把实际上小于val_mid的减去
28 }
29 }
30 int lpos = l;
31 int rpos = mid+1;
32 int same = 0;
33 for(int i = l ; i <= r ; i ++) {
34 if(i == l) {
35 toLeft[d][i] = 0;//toLeft[i]表示[ tt[idx].left , i ]区域里有多少个数分到左边
36 } else {
37 toLeft[d][i] = toLeft[d][i-1];
38 }
39 if(val[d][i] < sorted[mid]) {
40 toLeft[d][i] ++;
41 val[d+1][lpos++] = val[d][i];
42 } else if(val[d][i] > sorted[mid]) {
43 val[d+1][rpos++] = val[d][i];
44 } else {
45 if(same < lsame) {//有lsame的数是分到左边的
46 same ++;
47 toLeft[d][i] ++;
48 val[d+1][lpos++] = val[d][i];
49 } else {
50 val[d+1][rpos++] = val[d][i];
51 }
52 }
53 }
54 build(l,mid,d+1,LL(idx));
55 build(mid+1,r,d+1,RR(idx));
56 }
57
58 int query(int l,int r,int k,int d,int idx) {
59 if(l == r) {
60 return val[d][l];
61 }
62 int s;//s表示[ l , r ]有多少个分到左边
63 int ss;//ss表示 [tt[idx].left , l-1 ]有多少个分到左边
64 if(l == tt[idx].left) {
65 s = toLeft[d][r];
66 ss = 0;
67 } else {
68 s = toLeft[d][r] - toLeft[d][l-1];
69 ss = toLeft[d][l-1];
70 }
71 if(s >= k) {//有多于k个分到左边,显然去左儿子区间找第k个
72 int newl = tt[idx].left + ss;
73 int newr = tt[idx].left + ss + s - 1;//计算出新的映射区间
74 return query(newl,newr,k,d+1,LL(idx));
75 } else {
76 int mid = tt[idx].mid();
77 int bb = l - tt[idx].left - ss;//bb表示 [tt[idx].left , l-1 ]有多少个分到右边
78 int b = r - l + 1 - s;//b表示 [l , r]有多少个分到右边
79 int newl = mid + bb + 1;
80 int newr = mid + bb + b;
81 return query(newl,newr,k-s,d+1,RR(idx));
82 }
83 }
84
85 int main() {
86 int T;
87 scanf("%d",&T);
88 while(T --) {
89 int n , m;
90 scanf("%d%d",&n,&m);
91 for(int i = 1; i <= n; i++){
92 scanf("%d",&val[0][i]);
93 sorted[i] = val[0][i];
94 }
95 sort(sorted + 1 , sorted + n + 1);
96 build(1,n,0,1);
97 while(m --) {
98 int l,r,k;
99 scanf("%d%d%d",&l,&r,&k);
100 printf("区间第K小:%d\n",query(l,r,k,0,1));
101 k = r - l + 2 - k;
102 printf("区间第K大:%d\n",query(l,r,k,0,1));
103 }
104 }
105 return 0;
106 }