求逆序數之分治排序

2021-06-03 22:30:42 字數 996 閱讀 3141

求逆序數

時間限制: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萬個數的測試資料最多只有一組。

輸出 輸出該數列的逆序數

樣例輸入 22

1 13

1 3 2樣例輸出

0思路:先分治後歸併

ac**:

#include#include#include#define n 1000001

using namespace std;

long a[n],b[n];

long long num;//尼瑪的這裡讓我錯了好幾次。。。

void merge(int p,int q,int r,int s)

}if(a1>q)

for(;c<=s;++c)

b[k++]=a[c];

if(c>s)

for(;a1<=q;++a1)

b[k++]=a[a1];

for(;p>case;

while(case--)

{ memset(a,0,sizeof(a));

memset(b,0,sizeof(b));

num=0;

int n;

cin>>n;

for(int i=0;i>a[i];

merge_sort(0,n-1);

cout<

分治 求 逆序數

利用歸併,逆序數等於 左邊逆序數 右邊逆序數,加上 左邊 的每個數與右邊的每個數構成的逆序數。歸併過程 把 左邊和右邊按照從小到大排序 在 merge過程中發現a 右邊 a 左邊 說明 在此左邊p1位置的右側的數都能與 此時的p2位置的 a p2 構成逆序對。故 逐一對a j 進行判斷,累加即可得到...

分治求逆序數(CDQ)

歸併排序 includeusing namespace std int b 100 void merge sort int l,int r,int a else for int i l i r i a i b i int main merge sort 0,9,c for int i 0 i 10 ...

分治法求逆序數

include include include include using namespace std int arr2 100 在對序列進行二路歸併排序的時候,要將序列拆分成若干子串行,先將子串行排序,再合併子串行構成最終排序後的序列。二路歸併演算法還有乙個特點,在進行歸併操作時候的兩個子串行是有...