SPOJ INVCNT - how?

SPOJ INVCNT - how?

本文关键字:how INVCNT SPOJ      更新时间:2023-10-16

有人能帮我完成这项任务吗http://www.spoj.com/problems/INVCNT/。首先,我试着用BIT的方式思考,但我做不到。有人能用BIT解释这个任务的解决方案吗。BIT-二进制索引树c++

假设您知道如何在每次查询和使用BIT更新的O(log n)中解决以下问题:

Given an array A[1 .. n], implement the following functions efficiently:
query(x, y) = return A[x] + A[x+1] + ... + A[y]
update(x, v) = set A[x] = v

您可以这样解决当前的问题:首先,规范化数组值。这意味着您必须转换所有值,使它们处于区间[1, n]中。你可以通过排序来实现。例如,5, 2, 8将变成2, 1, 3。(注:1、2、3是按5、2、8排序的索引)

然后,对于每个i,我们将回答A[i]用元素j < i生成了多少个逆。为此,我们需要找到i之前大于i的元素的数量。这相当于query(A[i] + 1, n)

在这个查询之后,我们执行update(A[i], 1)

这是如何工作的:我们的BIT数组最初将填充零。在该数组中的位置k处的1意味着我们在迭代给定数组时遇到了值k。通过调用query(A[i] + 1, n),我们可以发现A[i]在它之前的元素生成了多少个逆,因为我们查询到目前为止迭代了多少比它大的元素。

找到这些之后,我们需要将A[i]标记为已访问。我们通过更新BIT数组中的位置A[i]并在其上加一个1来实现这一点:update(A[i], 1)

由于数组中的数字从1n不同,所以BIT数组的大小为n,并且复杂性在n中是对数的。

如果你想了解如何解决最初问题的详细信息,就写吧,尽管这是一个经典,你应该能够在谷歌上轻松找到代码。

注意:这个问题还有一个使用合并排序的漂亮解决方案,您可能需要考虑。