算法-小红的子序列逆序对

56 阅读1分钟

image.png

image.png

MOD = 10**9 + 7

def count_subsequence_inversions(a):
    n = len(a)
    if n < 2:
        return 0
    
    # 离散化数组
    sorted_a = sorted(set(a))
    mapping = {val: idx + 1 for idx, val in enumerate(sorted_a)}
    arr = [mapping[x] for x in a]
    m = len(sorted_a)
    
    # 树状数组实现
    tree = [0] * (m + 1)
    
    def update(index, delta):
        while index <= m:
            tree[index] += delta
            index += index & -index
            
    def query(index):
        s = 0
        while index:
            s += tree[index]
            index -= index & -index
        return s
    
    inversion_count = 0
    # 从后向前遍历,统计逆序对
    for i in range(n - 1, -1, -1):
        x = arr[i]
        if x > 1:
            inversion_count += query(x - 1)
        update(x, 1)
    
    # 计算 2^(n-2) mod MOD
    power = pow(2, n - 2, MOD)
    total_inversions = inversion_count * power % MOD
    return total_inversions

image.png