【问题标题】:Number of inversions in permutation if subarray of permutation is reversed?如果排列的子数组被反转,则排列中的反转次数?
【发布时间】:2016-06-23 16:43:12
【问题描述】:

我有 permutation(P) 的数字 1N (<=10^5) 。假设我可以反转 permutation 的子数组。我必须找到summation(X*Y),其中xP 通过反转P 的任何子数组可以采取的形式数量,y 是此类形式的总反转。

例如

if N =2 ; and given permutation = 2 1

Then summation(X*Y) = 

if i reverse subarray(1,1) = permutation = 2 1 inversion =1

if i reverse subarray(2,2) = permutation = 2 1 inversions =1 


if i reverse subarray(1,2) = permutation = 1 2 inversion =0 

summation (x*y) = 2*1 + 1*0 = 2 

我的方法是选择每个n*(n+1)/2子数组并将其反转,计算其中的倒数并求和,Complexity= O(n(n+1)/2*nlogn)=O(n^3logn)

O(nlogn)的方法吗?

https://en.wikipedia.org/wiki/Inversion_(discrete_mathematics)

【问题讨论】:

    标签: algorithm


    【解决方案1】:

    tl;dr:修改标准的二叉索引树算法以计算反转。

    在伪代码中,标准算法是

    # permutation is p[1..n]
    inversions <- 0
    let a[1..n] be a zeroed BIT
    for i from 1 to n
        inversions <- inversions + sum(a[p[i]+1..n])  # sum is O(log n)-time via BIT
        a[p[i]] <- 1
    end for
    

    我们没有将元素的 BIT 条目设置为 1,而是将其设置为 i,即可能包含该元素的间隔的左端点数。然后我们将总和乘以可能包含当前元素的区间的右端点数——这就是反转该对的区间数。

    # permutation is p[1..n]
    inversions <- 0
    let a[1..n] be a zeroed BIT
    let b[1..n] be a zeroed BIT
    for i from 1 to n
        inversions <- (inversions
            +                               sum(b[1..p[i]-1])*(n+1-i)   # inversions created by reversal
            + sum(a[p[i]+1..n])*(n+1)*n/2 - sum(b[p[i]+1..n])*(n+1-i))  # inversions not destroyed by reversal
        a[p[i]] <- 1
        b[p[i]] <- i
    end for
    

    【讨论】:

    • 上述算法给出了上述输入 2 , 1 的另一个结果。它给出 5 而答案是 2
    • 我认为所陈述的问题通过反转所有子数组减少了从原始排列派生的所有排列的求和求和,而您的反转超出了上述范围。如果我错了,请纠正我
    • 请您对使用两个 BIT 多加一点解释
    猜你喜欢
    • 2017-01-18
    • 2012-07-23
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    相关资源
    最近更新 更多