import
java.util.*;
class
Main {
static
final
int
N =
4
;
static
void
update(
int
l,
int
r,
int
val,
int
[][] bit) {
for
(
int
i = l; i <= N; i += i & -i)
for
(
int
j = r; j <= N; j += j & -j)
bit[i][j] += val;
}
static
long
query(
int
l,
int
r,
int
[][] bit) {
long
ret =
0
;
for
(
int
i = l; i >
0
; i -= i & -i)
for
(
int
j = r; j >
0
; j -= j & -j)
ret += bit[i][j];
return
ret;
}
static
long
countInversionPairs(
int
[][] mat) {
int
[][] bit =
new
int
[N +
1
][N +
1
];
List<AbstractMap.SimpleEntry<Integer, AbstractMap.SimpleEntry<Integer, Integer>>> v =
new
ArrayList<>();
for
(
int
i =
0
; i < N; ++i)
for
(
int
j =
0
; j < N; ++j)
v.add(
new
AbstractMap.SimpleEntry<Integer, AbstractMap.SimpleEntry<Integer, Integer>>(-mat[i][j],
new
AbstractMap.SimpleEntry<Integer, Integer>(i +
1
, j +
1
)));
Collections.sort(v,
new
Comparator<AbstractMap.SimpleEntry<Integer, AbstractMap.SimpleEntry<Integer, Integer>>>() {
@Override
public
int
compare(AbstractMap.SimpleEntry<Integer, AbstractMap.SimpleEntry<Integer, Integer>> a, AbstractMap.SimpleEntry<Integer, AbstractMap.SimpleEntry<Integer, Integer>> b) {
return
a.getKey().compareTo(b.getKey());
}
});
long
invPairCnt =
0
;
int
i =
0
;
while
(i < v.size()) {
int
curr = i;
List<AbstractMap.SimpleEntry<Integer, Integer>> pairs =
new
ArrayList<>();
while
(curr < v.size() && (v.get(curr).getKey().equals(v.get(i).getKey()))) {
pairs.add(v.get(curr).getValue());
invPairCnt += query(v.get(curr).getValue().getKey(), v.get(curr).getValue().getValue(), bit);
curr++;
}
for
(AbstractMap.SimpleEntry<Integer, Integer> p : pairs) {
int
x = p.getKey();
int
y = p.getValue();
update(x, y,
1
, bit);
}
i = curr;
}
return
invPairCnt;
}
public
static
void
main(String[] args) {
int
[][] mat = {{
4
,
7
,
2
,
9
}, {
6
,
4
,
1
,
7
}, {
5
,
3
,
8
,
1
}, {
3
,
2
,
5
,
6
}};
long
invPairCnt = countInversionPairs(mat);
System.out.println(
"The number of inversion pairs are: "
+ invPairCnt);
}
}