fork download
  1. import java.io.*;
  2. import java.util.*;
  3.  
  4. /**
  5.  * @username: sriman_chetan
  6.  * @author: Chetan Raikwar
  7.  * @date: 28-10-2020
  8.  */
  9. class Solution {
  10.  
  11. public static void main(String[] args) throws IOException {
  12.  
  13.  
  14. StringTokenizer input = new StringTokenizer(reader.readLine());
  15.  
  16. int n = Integer.parseInt(input.nextToken());
  17. int m = Integer.parseInt(input.nextToken());
  18.  
  19. input = new StringTokenizer(reader.readLine());
  20.  
  21. Pair[] a = new Pair[n];
  22.  
  23. for (int i = 0; i < n; i++) {
  24. int num = Integer.parseInt(input.nextToken());
  25. a[i] = new Pair(num, i);
  26. }
  27.  
  28. Arrays.sort(a);
  29.  
  30. MergesortTree mergesortTree = new MergesortTree(a, n);
  31. //mergesortTree.showTree();
  32.  
  33. while (m-- > 0) {
  34.  
  35. input = new StringTokenizer(reader.readLine());
  36. int i = Integer.parseInt(input.nextToken());
  37. int j = Integer.parseInt(input.nextToken());
  38. int k = Integer.parseInt(input.nextToken());
  39.  
  40. k = (k > (j - i + 1)) ? -1 : mergesortTree.kthSmallest(i, j, k);
  41. writer.println(k);
  42. // writer.println("------------------------------------------------------");
  43.  
  44. }
  45. }
  46. }
  47. }
  48.  
  49. class MergesortTree {
  50.  
  51. final int n;
  52. final Pair[] a;
  53. List<Pair>[] tree;
  54.  
  55. public MergesortTree(Pair[] list, int size) {
  56. n = size - 1;
  57. a = list;
  58. tree = new List[4 * size + 1];
  59.  
  60. constructTree(0, 0, n);
  61. }
  62.  
  63. public Integer kthSmallest(int left, int right, int k) {
  64. return kthSmallestQuery(0, 0, n, left - 1, right - 1, k);
  65. }
  66.  
  67. private Integer leftChild(int node) {
  68. return 2 * node + 1;
  69. }
  70.  
  71. private Integer rightChild(int node) {
  72. return 2 * node + 2;
  73. }
  74.  
  75. private Integer upperBound(final List<Pair> a, final int key) {
  76.  
  77. int low = 0, high = a.size() - 1;
  78.  
  79. if (key < a.get(low).index) {
  80. return low;
  81. }
  82.  
  83. if (key >= a.get(high).index) {
  84. return high;
  85. }
  86.  
  87. while (low <= high) {
  88.  
  89. int mid = (low + high) / 2;
  90.  
  91. if (a.get(mid).index <= key) {
  92.  
  93. if ((mid + 1) < n && a.get(mid + 1).index > key) {
  94. return mid + 1;
  95. }
  96. low = mid + 1;
  97. } else {
  98. high = mid - 1;
  99. }
  100. }
  101.  
  102. return a.size() - 1;
  103. }
  104.  
  105. private Integer lowerBound(final List<Pair> a, final int key) {
  106.  
  107. int low = 0, high = a.size() - 1;
  108.  
  109. if (key <= a.get(low).index) {
  110. return low;
  111. }
  112.  
  113. if (key >= a.get(high).index) {
  114. return high;
  115. }
  116.  
  117. while (low <= high) {
  118.  
  119. int mid = (low + high) / 2;
  120.  
  121. if (a.get(mid).index >= key) {
  122.  
  123. if ((mid - 1) >= 0 && a.get(mid - 1).index < key) {
  124. return mid;
  125. }
  126. high = mid - 1;
  127. } else {
  128. low = mid + 1;
  129. }
  130. }
  131.  
  132. return a.size() - 1;
  133. }
  134.  
  135. private void constructTree(int node, int low, int high) {
  136.  
  137. if (low == high) {
  138. tree[node] = new ArrayList<>();
  139. tree[node].add(a[low]);
  140. return;
  141. }
  142.  
  143. int mid = (low + high) / 2;
  144. int left = leftChild(node);
  145. int right = rightChild(node);
  146.  
  147. tree[node] = new ArrayList<>();
  148. tree[left] = new ArrayList<>();
  149. tree[right] = new ArrayList<>();
  150.  
  151. constructTree(left, low, mid);
  152. constructTree(right, mid + 1, high);
  153.  
  154. int i = 0, j = 0;
  155. int leftEnd = tree[left].size(), rightEnd = tree[right].size();
  156.  
  157. while (i < leftEnd && j < rightEnd) {
  158.  
  159. if (tree[left].get(i).index <= tree[right].get(j).index) {
  160. tree[node].add(tree[left].get(i++));
  161. } else {
  162. tree[node].add(tree[right].get(j++));
  163. }
  164. }
  165.  
  166. while (i < leftEnd) {
  167. tree[node].add(tree[left].get(i++));
  168. }
  169.  
  170. while (j < rightEnd) {
  171. tree[node].add(tree[right].get(j++));
  172. }
  173. }
  174.  
  175. private Integer kthSmallestQuery(int node, int low, int high, int left, int right, int k) {
  176.  
  177. if (low == high) {
  178. return tree[node].get(0).value;
  179. }
  180.  
  181. int mid = (low + high) / 2;
  182. int LEFT = leftChild(node);
  183. int RIGHT = rightChild(node);
  184.  
  185. int greaterThanK = upperBound(tree[LEFT], right);
  186. int smallerThanK = lowerBound(tree[LEFT], left);
  187.  
  188. int m = greaterThanK - smallerThanK;
  189.  
  190. // System.out.println((left + 1) + "\t" + (right + 1) + "\t" + (node + 1) + "\t" + (smallerThanK + 1) + "\t" + (greaterThanK + 1) + "\t" + m + "\t" + (k));
  191. if (m >= k) {
  192. return kthSmallestQuery(LEFT, low, mid, left, right, k);
  193. } else {
  194. return kthSmallestQuery(RIGHT, mid + 1, high, left, right, k - m);
  195. }
  196.  
  197. }
  198.  
  199. public void showTree() {
  200.  
  201. for (int i = 0; i < tree.length; i++) {
  202. if (tree[i] != null) {
  203. System.out.println(tree[i]);
  204. }
  205. }
  206. }
  207. }
  208.  
  209. class Pair implements Comparable<Pair> {
  210.  
  211. final int value, index;
  212.  
  213. public Pair(int value, int index) {
  214.  
  215. this.value = value;
  216. this.index = index;
  217. }
  218.  
  219. @Override
  220. public int compareTo(Pair p) {
  221. return this.value - p.value;
  222. }
  223.  
  224. @Override
  225. public String toString() {
  226. return "(" + value + " " + index + ")";
  227. }
  228. }
  229.  
Success #stdin #stdout 0.06s 32920KB
stdin
7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3
stdout
6
7
4