![](/img/trans.png)
[英]How to count number of inversions for large number of inputs using merge sort
[英]Difficulty understanding code to count the number of inversions using BIT
這是代碼:
#include<iostream>
using namespace std;
const int MX = 100;
int n,a[MX*2],bit[MX];
void add(int x, int y){
for(;x<=n; x+=-x&x) bit[x]+=y;
}
int query(int x){
int s= 0;
for(;x>0; x-=-x&x) s+=bit[x];
return s;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ans = 0;
cin >> n; n*=2;
for(int i = 0; i<n; i++){
cin >> a[i];
}
for(int i = n-1; ~i; i--){
ans+=query(a[i]-1);
add(a[i],1);
}
cout << ans;
}
我不明白查詢和添加如何有助於查找數組中的反轉數。 如果有人可以幫助向我解釋這一點,那就太好了。 謝謝。
首先,我希望您了解BIT
中的add
和query
是如何工作的。 如果不是,請將BIT
視為一個黑盒,它存儲數組A
中元素1, 2, ..., n
的計數的前綴總和。 例如, A[3] = count(1) + count(2) + count(3)
。 add(x, y)
count(x)
增加y
並且query(x)
返回總和count(1) + count(2) +... + count(x)
即前綴 sum 直到元素x
。
如果i < j
和arr[i] > arr[j]
,索引i
和j
處的元素形成反轉。 但是上面的代碼以另一種方式讀取它; j > i
和arr[j] < arr[i]
(這節省了對query
的額外調用)。
現在假設數組是{3, 4, 1, 5, 2}
並且{2, 5, 1}
已經插入到BIT
中。 然后query(1) = 1
, query(2) = 2
, query(3) = 2
, query(4) = 2
和query(5) = 3
(請記住將BIT
視為存儲前綴和的黑盒)。 請注意,當索引i
指向元素4
時,所有已插入的具有索引j1, j2, ..., jk
的元素都是> i
所以現在我們只需要計算元素的數量< 4
這是前綴通過調用query(3)
得到的總和直到3
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.