今兒開啟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 ...