転倒数

値を座標圧縮し、左から順に「それより前にある、自分より大きい値の個数」を BIT(Fenwick Tree)で数えて足します。

隣り合う 2 つの要素の交換をくり返して $a$ を昇順に並べるとき、交換の最小回数は転倒数に等しくなります。

コード

def inversion_count(a):
    # i < j かつ a[i] > a[j] となる組 (i, j) の個数
    vals = sorted(set(a))
    idx = {x: i + 1 for i, x in enumerate(vals)}
    m = len(vals)
    bit = [0] * (m + 1)
    res = 0
    for i, x in enumerate(a):
        k = idx[x]
        # これまでに出てきた x 以下の値の個数を数え、残りを足す
        j = k
        s = 0
        while j:
            s += bit[j]
            j -= j & -j
        res += i - s
        while k <= m:
            bit[k] += 1
            k += k & -k
    return res