找出增加子序列的数量

时间:2014-12-10 17:23:08

标签: c++ algorithm binary-search-tree

我想找到一个数组中增加的子序列的数量,我遇到了一个二进制索引树,它为我们提供了O(log n)解决方案。

我无法理解用于BIT的代码:

void madd(int& a, int b)
{
    a += b;
}

// fenwick code
void update(int i, int x)
{
    for (++i; i < MAX_N; i += i & -i) madd(ft[i], x);
}

int query(int i)
{
    int s = 0;
    for (++i; i > 0; i -= i & -i) madd(s, ft[i]);
    return s;
}

for (int i = 0; i < N; i++)
{
    dp[i] = 1 + query(H[i] - 1); // H[i] contains the our number array

    update(H[i], dp[i]);
}

请帮我理解。
谢谢

1 个答案:

答案 0 :(得分:2)

算法的想法很简单:

  1. 让我们创建一个数组f,其中f[i]是将i作为最后一个元素的递增子序列的数量。最初它充满了零。

  2. 让我们迭代初始数组的所有元素并更新f值。如果当前元素是h,那么我们可以将它添加到所有增加的子序列中,这些子序列的最后一个元素小于h,或者创建一个仅包含该数字的新子序列。这就是dp[i] = sum(f[j]) + 10 <= j < h的原因。

  3. BIT可用于在数组的前缀上查找总和并有效地更新一个元素(步骤2需要它),这就是它用于存储f值的原因。