范围查询O(lg N)中的反转次数

时间:2015-04-28 04:47:16

标签: algorithm data-structures segment-tree fenwick-tree

给定n个整数的未排序数组,我知道我可以按照这种方法在O(N lg N)中找到使用BIT的反转总数:Count Inversion by BIT

但是,如果我必须查询O(lg N)中反转总数的任意范围,是否可能?

O(N lg N)预计算是可以接受的。

我做了一些研究,似乎N因素是不可避免的...... 任何建议,将不胜感激!

1 个答案:

答案 0 :(得分:0)

这不是您正在寻找的答案,但我有两个建议。

首先,我认为BIT不是用于解决问题的正确数据结构。 BIT的优点是它每次插入仅使用O(lg n)维护O(lg n)可查询前缀和。由于您在数据结构完成后没有插入,因此BIT不是有利的(因为您可以使用简单的前缀和数组,可以在O(1)中查询)。

其次,我有一个天真的算法,它使用O(n 2 )时间和空间构建一个可以在O(1)时间内找到范围反转的数据结构:

首先,构造一个映射反转的(n X n)矩阵,以便仅mat[i][j]=1i<jarr[i]被反转时才arr[j]。然后,计算此矩阵每行的前缀和,以便mat[i][j]arr[i]范围内涉及[i,j]的反转次数。最后,计算每列的后缀总和,以便mat[i][j][i,j]范围内的反转总数。

for i from 0 to n-2
  for j from i+1 to n-1
    if(arr[j] > arr[i])
      mat[i][j] = 1;
for i from 0 to n-2
  for j from i+1 to n-1
    mat[i][j] += mat[i][j-1];
for j from n-1 to 1
  for i from j-1 to 0
    mat[i][j] += mat[i+1][j];

这显然需要O(n 2 )时间和空间,但可以在恒定时间内查询任何范围内的反转次数。