SPOJ INVCNT - how?
SPOJ INVCNT - how?
有人能帮我完成这项任务吗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)
。
由于数组中的数字从1
到n
不同,所以BIT数组的大小为n
,并且复杂性在n
中是对数的。
如果你想了解如何解决最初问题的详细信息,就写吧,尽管这是一个经典,你应该能够在谷歌上轻松找到代码。
注意:这个问题还有一个使用合并排序的漂亮解决方案,您可能需要考虑。
相关文章:
- OpenGL VBO Indexing ( How to compute Index Array)
- How to recover system gcc compiler on centos 6
- "How to make a recursive call for palindrom numbers without reverse function in c++?"
- How can I std::sqrt(boost::lambda::placeholder1_type)?
- "How to use long long data-type rather than pointers data-type to modify other variables ?"
- "How to pass String value in between URL in C/C++?"
- "Segfault using proj4 with OpenMP"或"How to use thread-specific globals with OpenMP"
- How does c++11 std::ref work?
- How to `decltype` a functors operator()?
- How to std::forward( *this )
- HippoMocks: How to ExpectCall 使用通过引用传递的参数
- how to #define c++ STL macro
- How to: CUDA IFFT
- 对简单的帐户检查程序有问题?程序返回编译错误,指出"no match for 'operator||' unsure of how to fix?"
- How to DllImport char*
- QFile.write( myStruct ) - how?
- How to Blend two texture in OpenGL ES 1
- How does duration_cast round
- LNK2001 "How can I make a WNDPROC or DLGPROC a member of my C++ class?"
- SPOJ INVCNT - how?