任何人都可以帮我完成这项任务http://www.spoj.com/problems/INVCNT/。首先,我尝试用BIT方式思考,但我不能。任何人都可以用BIT解释这个任务的解决方案。 BIT-二进制索引树 C ++
答案 0 :(得分:5)
假设您知道如何在每个查询的O(log n)
中解决以下问题并使用BIT进行更新:
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)
。
由于数组中的数字不同于1
到n
,因此您的BIT数组的大小为n
,复杂性在n
中是对数的。
如果您想了解如何解决最初问题的详细信息,请写一下,尽管这是一个经典之作,您应该可以在Google上轻松找到代码。
注意:此问题还有一个使用您可能想要考虑的merge sort的漂亮解决方案。