日更 2019 6 29 逆序對問題

2021-09-24 20:37:04 字數 1755 閱讀 8807

今兒開啟51nod

玩了一下

啥都不會

只會寫a+b

複習一下歸併排序

#include.h>

using namespace std;

void

merge

(int a,

int l1,

int r1,

int l2,

int r2)

else

}while

(i<=r1)temp[index++

]=a[i++];

while

(j<=r2)temp[index++

]=a[j++];

for(i=

0;ivoid

mergesort

(int a,

int l,

int r)

}int

main()

for(

int i=

0;i)return0;

}

歸併排序可以上公升到逆序對的問題

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

如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序數是4。給出乙個整數序列,求該序列的逆序數。

這個題目可以用暴力o(n2)演算法,動態規劃o(nlogn)

#include.h>

using namespace std;

const

int n =

500000

;int swap_space[n]

;//歸併排序的交換空間

long

long total;

//逆序數

void

merge

(int a,

int begin,

int mid,

int end)

else

}while

(i <= mid)

swap_space[k++

]= a[i++];

while

(j <= end)

swap_space[k++

]= a[j++];

for(i = begin; i <= end; i++)}

void

mergesort

(int a,

int begin,

int end)

}int

main()

mergesort

(a,0

,n-1);

cout

}

那麼為什麼可以用歸併來計算逆序對呢?

首先兩個組別的陣列之間的元素交換不影響答案,所以在交換過程中累加答案。

其次,兩個組別的元素滿足這樣的關係

a=,b=並且在原陣列中滿足c=的順序

如果a[i]>b[j],則ans+=len(a)-i

eg. a=,b=,c=

那麼首先對a,b排序

a又變成兩個陣列

然後排序

於是答案+1

同理b排序,答案+1

於是乎此時a=,b=,c=

在應用上面的公式歸併排序一遍

答案+2+2

於是答案為6

解答完畢

逆序對問題

逆序對問題。給一列數a1 a2,an 求它的逆序對數,即有多少個有序對 i j 使得 i j 但ai aj n 可以高達106 由於 n 的數量級到了106 所以採用o n2 及以上的時間複雜度肯定會超時,所以必須選取o nlog 2n 及以下時間複雜度的演算法。逆序對的求解思路和歸併排序很像,嘗試...

逆序對問題 O nlgn

問題描述 在陣列arr中,i j 如果 arr i arr j 那麼就存在乙個逆序對 目的就是求出逆序對的數目。演算法 暴力求解,o n 2 下面運用了一種很巧妙的方法,通過歸併排序的歸併過程,進行逆序對的統計!具體例子分析 比如 1 5 3 2 4 當 1 3 5 與 2 4 合併的時候,a.1 ...

逆序對問題 O nlgn

問題描述 在陣列arr中,i j 如果 arr i arr j 那麼就存在乙個逆序對 目的就是求出逆序對的數目。演算法 暴力求解,o n 2 下面運用了一種很巧妙的方法,通過歸併排序的歸併過程,進行逆序對的統計!具體例子分析 比如 1 5 3 2 4 當 1 3 5 與 2 4 合併的時候,a.1 ...