import
java.util.*;
public
class
mergeSortTree {
static
void
buildTree(
int
idx,
int
ss,
int
se,
ArrayList<Integer> a[],
ArrayList<Integer> tree[])
{
if
(ss == se) {
tree[idx] = a[ss];
return
;
}
int
mid = (ss + se) >>
1
;
buildTree(
2
* idx +
1
, ss, mid, a, tree);
buildTree(
2
* idx +
2
, mid +
1
, se, a, tree);
tree[idx]
= merge(tree[
2
* idx +
1
], tree[
2
* idx +
2
]);
}
static
int
upbound(ArrayList<Integer> temp,
int
val)
{
int
lo =
0
;
int
hi = temp.size() -
1
;
while
(hi >= lo) {
int
mid = (lo + hi) >>
1
;
if
(temp.get(mid) <= val) {
lo = mid +
1
;
}
else
hi = mid -
1
;
}
return
lo;
}
static
int
queryRec(
int
node,
int
start,
int
end,
int
ss,
int
se,
int
k,
ArrayList<Integer> a[],
ArrayList<Integer> tree[])
{
if
(ss > end || se < start)
return
0
;
if
(ss <= start && se >= end) {
return
upbound(tree[node], k);
}
int
mid = (start + end) /
2
;
int
q1 = queryRec(
2
* node +
1
, start, mid, ss, se,
k, a, tree);
int
q2 = queryRec(
2
* node +
2
, mid +
1
, end, ss,
se, k, a, tree);
return
q1 + q2;
}
static
int
query(
int
start,
int
end,
int
k,
ArrayList<Integer> a[],
int
n,
ArrayList<Integer> sTree[])
{
return
queryRec(
0
,
0
, n -
1
, start, end, k, a,
sTree);
}
static
ArrayList<Integer> merge(ArrayList<Integer> a,
ArrayList<Integer> b)
{
ArrayList<Integer> res =
new
ArrayList<>(a);
res.addAll(b);
Collections.sort(res);
return
res;
}
public
static
void
main(String[] args)
{
int
n =
3
;
int
[][] arr
= { {
2
,
4
,
5
}, {
3
,
4
,
9
}, {
6
,
8
,
10
} };
ArrayList<Integer> a[] =
new
ArrayList[n];
for
(
int
i =
0
; i < n; i++) {
a[i] =
new
ArrayList<Integer>();
for
(
int
j =
0
; j < n; j++)
a[i].add(arr[i][j]);
}
ArrayList<Integer> tree[]
=
new
ArrayList[
4
* n];
buildTree(
0
,
0
, n -
1
, a, tree);
System.out.println(query(
0
,
1
,
5
, a, n, tree));
System.out.println(query(
1
,
2
,
1
, a, n, tree));
System.out.println(query(
0
,
2
,
6
, a, n, tree));
}
}