// C++ program to count the number of inversion
// pairs in a 2D matrix
#include <bits/stdc++.h>
using namespace std;
 
// for simplicity, we are taking N as 4
#define N 4
 
// Function to update a 2D BIT. It updates the
// value of bit[l][r] by adding val to bit[l][r]
void update(int l, int r, int val, int bit[][N + 1])
{
    for (int i = l; i <= N; i += i & -i)
        for (int j = r; j <= N; j += j & -j)
            bit[i][j] += val;
}
 
// function to find cumulative sum upto
// index (l, r) in the 2D BIT
long long query(int l, int r, int bit[][N + 1])
{
    long 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;
}
 
// function to count and return the number
// of inversion pairs in the matrix
long long countInversionPairs(int mat[][N])
{
    // the 2D bit array and initialize it with 0.
    int bit[N+1][N+1] = {0};
 
    // v will store the tuple (-mat[i][j], i, j)
    vector<pair<int, pair<int, int> > > v;
 
    // store the tuples in the vector v
    for (int i = 0; i < N; ++i)
        for (int j = 0; j < N; ++j)
 
            // Note that we are not using the pair
            // (0, 0) because BIT update and query
            // operations are not done on index 0
            v.push_back(make_pair(-mat[i][j],
                        make_pair(i+1, j+1)));
 
    // sort the vector v according to the
    // first element of the tuple, i.e., -mat[i][j]
    sort(v.begin(), v.end());
 
    // inv_pair_cnt will store the number of
    // inversion pairs
    long long inv_pair_cnt = 0;
 
    // traverse all the tuples of vector v
    int i = 0;
    while (i < v.size())
    {
        int curr = i;
 
        // 'pairs' will store the position of each element,
        // i.e., the pair (i, j) of each tuple of the vector v
        vector<pair<int, int> > pairs;
 
        // consider the current tuple in v and all its
        // adjacent tuples whose first value, i.e., the
        // value of –mat[i][j] is same
        while (curr < v.size() &&
               (v[curr].first == v[i].first))
        {
            // push the position of the current element in 'pairs'
            pairs.push_back(make_pair(v[curr].second.first,
                                      v[curr].second.second));
 
            // add the number of elements which are
            // less than the current element and lie on the right
            // side in the vector v
            inv_pair_cnt += query(v[curr].second.first,
                                  v[curr].second.second, bit);
 
            curr++;
        }
 
        vector<pair<int, int> >::iterator it;
 
        // traverse the 'pairs' vector
        for (it = pairs.begin(); it != pairs.end(); ++it)
        {
            int x = it->first;
            int y = it->second;
 
            // update the position (x, y) by 1
            update(x, y, 1, bit);
        }
 
        i = curr;
    }
 
    return inv_pair_cnt;
}
 
// Driver program
int main()
{
    int mat[N][N] = { { 4, 7, 2, 9 },
                      { 6, 4, 1, 7 },
                      { 5, 3, 8, 1 },
                      { 3, 2, 5, 6 } };
 
    long long inv_pair_cnt = countInversionPairs(mat);
 
    cout << "The number of inversion pairs are : "
         << inv_pair_cnt << endl;
 
    return 0;
}

Time complexity: logn
Space complexity: quadratic