1. 程式人生 > >逆序對的求法(樹狀陣列)

逆序對的求法(樹狀陣列)

設A[1...n]是一個包含n個不同數的陣列,如果在i<j的情況下,有A[i]>A[j],則(i,j)就稱為A中的一個逆序對。

求法有兩種,一種是歸併排序,一種是樹狀陣列。二者的時間複雜度都是O(n*logn),但樹狀陣列更加好寫。

思路:開一個樹狀陣列A記錄每一個數出現的次數。倒序輸入,每輸入一個數num就在A中加1,同時求一下從0到num-1的字首和。

#include <iostream>
using namespace std;

void AddNum(int * arr, int iArrSize, int iIndex, int iNum)
{
	for (int i = iIndex; i <= iArrSize; i += (i & (-i)))
		arr[i] += iNum;
}

int GetSum(int * arr, int iIndex)
{
	int iAns = 0;
	for (int i = iIndex; i; i -= (i & (-i)))
		iAns += arr[i];
	return iAns;
}

int main()
{
	int iNumTot, arrSum[1010] = { 0 }, arrNum[1010] = { 0 };
	cin >> iNumTot;
	
	int iAns = 0;
	for (int i = 1; i <= iNumTot; i++)
		cin >> arrNum[i];
		
	for (int i = iNumTot; i >= 1; i--)
	{
		AddNum(arrSum, 1000, arrNum[i], 1);
		iAns += GetSum(arrSum, arrNum[i] - 1);
	}
	
	cout << iAns << endl;
	
	
	return 0;
}