nyoj 117 求逆序數 (歸併排序)

2021-07-30 18:47:39 字數 1066 閱讀 8872

求逆序數

時間限制:2000 ms | 記憶體限制:65535 kb

難度:5

描述 在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。

現在,給你乙個n個元素的序列,請你判斷出它的逆序數是多少。

比如 1 3 2 的逆序數就是1。

輸入 第一行輸入乙個整數t表示測試資料的組數(1<=t<=5)

每組測試資料的每一行是乙個整數n表示數列中共有n個元素(2〈=n〈=1000000)

隨後的一行共有n個整數ai(0<=ai<1000000000),表示數列中的所有元素。

資料保證在多組測試資料中,多於10萬個數的測試資料最多只有一組。

輸出 輸出該數列的逆序數

樣例輸入

2 2

1 1

3 1 3 2

樣例輸出

0 1

解題思路:首先看題目上的資訊,陣列很大,到百萬,普通的求法肯定會超時,這時我就想到了stl中有個求全排列的函式,借用它來求逆序數,結果依然超了,最後才不得不借用歸併排序來求逆序數,因為它不但穩定而且可以時間複雜度為nlogn,只需在合併的時候如果第乙個陣列的元素大於第二個陣列的元素就將第二個陣列後邊的元素加入到逆序數中。

#include 

#include

using

namespace

std;

long

long

int a[1000005],b[1000005],sum;

void merge(int low,int mid,int high)//合併

else b[k++]=a[j++];

}while(i<=mid)b[k++]=a[i++];

while(k--) a[low+k]=b[k];

}void mergesort(int left,int right)//將原陣列分成兩部分的有序陣列

int main()

return

0;}

nyoj 117 歸併求逆序數

花了一晚上和上午的時間終於除錯出來了,一開始沒有考慮到存在相等數字的情況 這裡有必要對歸併排序進行總結。分為分治三步法 1.劃分問題 把序列分成元素個數盡量相等的兩半 2.遞迴求解 把兩半元素分別排序 3.合併問題 把兩個有序表合併成乙個 此題求逆序中的第二步就是統計i,j均在左邊或者均在右邊的逆序...

nyoj117 求逆序數(歸併)

題意 時間限制 2000 ms 記憶體限制 65535 kb難度 5 描述在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。現在,給你乙個n個元素的序列,請你判斷出它的逆序數是多少。比如 1 3 2 的逆序數...

NYOJ117 求逆序數 歸併排序記錄次數

題目 時間限制 2000 ms 記憶體限制 65535 kb 難度 5 描述 在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。現在,給你乙個n個元素的序列,請你判斷出它的逆序數是多少。比如 1 3 2 的逆...