如果排列的子阵列被反转,则排列的反转次数是多少?

时间:2016-06-23 16:43:13

标签: algorithm

我有permutation(P)个号1N (<=10^5)。假设我可以颠倒排列的子阵列。我必须找到summation(X*Y),其中xP可以通过撤消Py的任何子阵列可以采取的形式数量,这些形式的完全反转

例如

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)

1 个答案:

答案 0 :(得分:0)

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