JXFCZX 求逆序對 歸併排序

2021-09-13 02:02:39 字數 1062 閱讀 1596

給定乙個序列a1,a2,…,an,如果存在 i < j 並且ai > aj,那麼我們稱之為逆序對,求逆序對的數目。

資料範圍:n<=10^5。ai<=10^5。時間限制為1s。

第一行為n,表示序列長度,接下來的n個數表示序列中的第i個數。

所有逆序對總數.

4

3 2 3 2

求逆序數可以通過管理兩個指標,兩次掃瞄陣列,暴力法求出,顯然時間複雜度是o(n^2).那麼有更快的辦法嗎?答案是肯定的。我們可以利用歸併排序法,稍做改進即可.

演算法:歸併排序是分治法(分而治之)的一種典型應用,應用遞迴的思想,自頂向下思考:先假定mergesort()可以將乙個亂序的陣列排好序,因此就可以開始"分"(將乙個陣列平均分成兩部分),再"治"(分別對前後部分呼叫mergesort()使它們有序),最後再寫乙個合併子函式merge(),它可以將兩個有序的陣列合併,merge()實現起來比較容易.只需要管理兩個指標,分別指向兩個子陣列的開頭,開闢新記憶體儲存中間結果,遍歷完兩個陣列就可以完成,時間複雜度是o(n).

求逆序數對時,在merge()中,合併兩個已經有序的陣列a、b.因為a、b有序,所以a,b各自的逆序數是0,故a、b的逆序數等於a,b之間的逆序數.

#include using namespace std;

long long ans = 0;

void merge(int a, int l, int mid, int r)

}while (p <= mid - 1)

temp[k++] = a[p++];

while (q <= r)

temp[k++] = a[q++];

for (int i = 0; i < k; i++)

a[i + l] = temp[i];

}void msort(int a, int l, int rightend)

}int main()

歸併排序求逆序對

排序都用qsort了,別的排序演算法不怎麼用,但有些排序的思想很重要。碰到一道求逆序對的題,要用到歸併排序,學習了一下歸併排序。歸併排序是用分治思想,分治模式在每一層遞迴上有三個步驟 分解 將n個元素分成個含n 2個元素的子串行。解決 用合併排序法對兩個子串行遞迴的排序。合併 合併兩個已排序的子串行...

歸併排序求逆序對

我們知道,求逆序對最典型的方法就是樹狀陣列,但是還有一種方法就是merge sort 即歸併排序。實際上歸併排序的交換次數就是這個陣列的逆序對個數,為什麼呢?我們可以這樣考慮 歸併排序是將數列a l,h 分成兩半a l,mid 和a mid 1,h 分別進行歸併排序,然後再將這兩半合併起來。在合併的...

歸併排序求逆序對

現在給定乙個有n個數的數列ai。若對於i j,有ai aj,則稱 i,j 為數列的乙個逆序對。例如,2,3,8,6,1 有五個逆序對,分別是 1,5 2,5 3,4 3,5 4,5 現在請你求出乙個給定數列的逆序對個數。輸入格式 乙個整數t,表示有多少組測試資料。每組測試資料第一行是乙個正整數n 1...