基本步驟:
1、分界點 mid=(l+r)/2
2、遞迴排序(left,right)
3、合二為一
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define ull unsigned long long
#define up_b upper_bound
#define low_b lower_bound
#define m_p make_pair
#define mem(a) memset(a,0,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define inf 0x3f3f3f3f
#include
using
namespace std;
inline ll read()
while
('0'
<=ch&&ch<=
'9') x=x*
10+ch-
'0', ch=
getchar()
;return f*x;
}const
int n =
1e5+5;
int n,a[n]
,l[n/2+
2],r[n/2+
2];void
mergesort
(int l,
int r)
}int
main()
巧用歸併排序:求陣列中逆序對的個數
利用歸併排序的特性,l陣列中的數相對與r陣列一定位於原陣列的左邊,那麼如果r中的數小於l中的數就會產生逆序對,又因為l陣列和r陣列本身是有序的,r中的某個數r[j]小於l中的某個數l[i],那麼(l[i],r[j])是乙個逆序對,同時r[j]與l[i]後面的數一定也是逆序對,因為l[i]<=l[i+1],而r[j]#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define ull unsigned long long
#define up_b upper_bound
#define low_b lower_bound
#define m_p make_pair
#define mem(a) memset(a,0,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define inf 0x3f3f3f3f
#include
using
namespace std;
inline ll read()
while
('0'
<=ch&&ch<=
'9') x=x*
10+ch-
'0', ch=
getchar()
;return f*x;
}const
int n =
5e5+5;
int n,a[n]
,l[n/2+
2],r[n/2+
2];ll ans=0;
void
mergesort
(int l,
int r)
}int
main()
OI學習筆記 歸併排序
根據分治三步走策略,歸併排序分為劃分,遞迴,合併三個步驟 複雜度o n log2n 把序列分成左右盡量等長的兩半 分別對左右兩邊進行歸併排序 問題是。怎麼把兩個有序序列合併成乙個大的有序序列?合併策略 每次比較左右兩個序列中最小的那乙個,將更小的那個加入輔助空間 因為已經有序,所以若a b,則a一定...
歸併排序筆記
將兩個的有序數列合併成乙個有序數列,我們稱之為 歸併 歸併排序 如果要將乙個陣列排序,可以先 遞迴地 將它們分成兩半進行排序,然後將結果歸併起來。下面介紹另外兩種方法,分別是自頂向下歸併和自底向上歸併,圖示參考連線 但是我感覺裡面的那個自下而上的演算法感覺有點複雜,所以我總結了演算法第四版上的 如下...
演算法學習筆記 歸併排序
歸併排序 一種簡單的利用遞迴排序的演算法,將乙個陣列先 遞迴地 將它分成兩半分別排序,然後將兩半分別排序,然後將結果歸併起來。原地歸併的抽象方法 public static void merge int a,int lo,int mid,int hi 歸併回a lo.hi for int k lo ...