import
java.io.*;
import
java.util.*;
class
GFG {
static
final
int
MAX =
1000
;
static
void
buildTree(
int
treeIndex,
int
l,
int
r,
List<Pair<Integer, Integer> > a,
List<List<Integer> > tree)
{
if
(l == r) {
tree.get(treeIndex).add(a.get(l).second);
return
;
}
int
mid = (l + r) /
2
;
buildTree(
2
* treeIndex, l, mid, a, tree);
buildTree(
2
* treeIndex +
1
, mid +
1
, r, a, tree);
List<Integer> leftChild = tree.get(
2
* treeIndex);
List<Integer> rightChild
= tree.get(
2
* treeIndex +
1
);
List<Integer> currentTree =
new
ArrayList<>();
int
leftIndex =
0
, rightIndex =
0
;
while
(leftIndex < leftChild.size()
&& rightIndex < rightChild.size()) {
if
(leftChild.get(leftIndex)
< rightChild.get(rightIndex)) {
currentTree.add(leftChild.get(leftIndex));
leftIndex++;
}
else
{
currentTree.add(rightChild.get(rightIndex));
rightIndex++;
}
}
while
(leftIndex < leftChild.size()) {
currentTree.add(leftChild.get(leftIndex));
leftIndex++;
}
while
(rightIndex < rightChild.size()) {
currentTree.add(rightChild.get(rightIndex));
rightIndex++;
}
tree.set(treeIndex, currentTree);
}
static
int
queryRec(
int
segmentStart,
int
segmentEnd,
int
queryStart,
int
queryEnd,
int
treeIndex,
int
K,
List<List<Integer> > tree)
{
if
(segmentStart == segmentEnd)
return
tree.get(treeIndex).get(
0
);
int
mid = (segmentStart + segmentEnd) /
2
;
List<Integer> leftChild = tree.get(
2
* treeIndex);
int
last_in_query_range
= upperBound(leftChild, queryEnd);
int
first_in_query_range
= lowerBound(leftChild, queryStart);
int
M = last_in_query_range - first_in_query_range;
if
(M >= K) {
return
queryRec(segmentStart, mid, queryStart,
queryEnd,
2
* treeIndex, K,
tree);
}
else
{
return
queryRec(mid +
1
, segmentEnd, queryStart,
queryEnd,
2
* treeIndex +
1
,
K - M, tree);
}
}
static
int
query(
int
queryStart,
int
queryEnd,
int
K,
int
n, List<Pair<Integer, Integer> > a,
List<Integer>[] tree)
{
return
queryRec(
0
, n -
1
, queryStart -
1
,
queryEnd -
1
,
1
, K, tree);
}
public
static
void
main(String[] args)
{
int
[] arr = {
3
,
2
,
5
,
1
,
8
,
9
};
int
n = arr.length;
List<Pair<Integer, Integer> > v
=
new
ArrayList<Pair<Integer, Integer> >();
for
(
int
i =
0
; i < n; i++) {
v.add(
new
Pair<Integer, Integer>(arr[i], i));
}
Collections.sort(
v,
new
Comparator<Pair<Integer, Integer> >() {
public
int
compare(Pair<Integer, Integer> a,
Pair<Integer, Integer> b)
{
return
a.getKey().compareTo(b.getKey());
}
});
List<Integer>[] tree =
new
List[n *
4
];
for
(
int
i =
0
; i < n *
4
; i++) {
tree[i] =
new
ArrayList<Integer>();
}
buildTree(
1
,
0
, n -
1
, v, tree);
int
kSmallestIndex = query(
2
,
5
,
2
, n, v, tree);
System.out.println(arr[kSmallestIndex]);
kSmallestIndex = query(
1
,
6
,
4
, n, v, tree);
System.out.println(arr[kSmallestIndex]);
}
}