現在給定乙個有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 <=n<= 100000),表示數列中有n個數字。
接下來一行包含n個正整數,代表對應的數列。
保證所有正整數小於 100000000。
輸出格式
對於每組資料,輸出一行,表示逆序對的個數。
樣例輸入
1
52 3 8 6 1
樣例輸出5
注意:
本題如果用普通的雙重迴圈遍歷求解問題,時間複雜度為o(n^2)會導致超時;
採用歸併排序,時間複雜度為o(nlogn)不會超時;
有乙個小陷阱,就是逆序對的個數可能會超過int的範圍,因為若整數序列是從100,000,000遞減,那麼逆序對的個數就會是
100,000,000*(100,000,000+1
)/2, 所以需要將其設定為long long 型別。
下面是本人的**:
#include#include#define max 100000
int n;
long long count;
int a[max];
void print(int a)
} while(i<=mid)
while(j<=high)
temp[ti++]=a[j++];
for(i=0;iusing namespace std;
const int n = 1e5+5;
typedef long long ll;
int n, a[n], b[n];
ll merge_sort(int l, int r)
int main()
}
歸併排序求逆序對
排序都用qsort了,別的排序演算法不怎麼用,但有些排序的思想很重要。碰到一道求逆序對的題,要用到歸併排序,學習了一下歸併排序。歸併排序是用分治思想,分治模式在每一層遞迴上有三個步驟 分解 將n個元素分成個含n 2個元素的子串行。解決 用合併排序法對兩個子串行遞迴的排序。合併 合併兩個已排序的子串行...
歸併排序求逆序對
我們知道,求逆序對最典型的方法就是樹狀陣列,但是還有一種方法就是merge sort 即歸併排序。實際上歸併排序的交換次數就是這個陣列的逆序對個數,為什麼呢?我們可以這樣考慮 歸併排序是將數列a l,h 分成兩半a l,mid 和a mid 1,h 分別進行歸併排序,然後再將這兩半合併起來。在合併的...
歸併排序求逆序對
求逆序對方法有兩種 樹狀陣列和歸併排序,還有暴力 暴力就是兩個for迴圈判斷當ia j 則ans 這裡先說歸併排序吧,在另一篇部落格中再講樹狀陣列求逆序對 實際上是我寫樹狀陣列的還有bug沒找到.include include include includeusing namespace std c...