分治與歸併(數列分治)

2021-08-22 04:55:57 字數 1845 閱讀 3961

通過兩個題目了解吧,是求逆序數的,就是運用分治與歸的思想,我自己的理解是:通過把該問題分解為好多的子問題,然後一次次胡歸併得到答案。

兩道題目的意思是一致的,都是數列分治的模板題目。

下面附兩個**,乙個是該題的模板code和詳細的解釋(注釋)。另乙個是學長的關於數列分治的演示**。

code one

#include //數列分治(求逆序對數目)。方法:分治與歸併。

#include #include #include #include #include #include #include #include #include #include #include #define _use_math_defines

using namespace std;

typedef long long ll;

const int maxn = 200000+5;

int a[maxn], b[maxn]; //a用於儲存資料,b用於調整當前區間中的元素位置,使之按從大到小的順序排列

ll sum = 0;//儲存結果

void guibing(int l, int mid, int r) //歸併函式:對分治(二分)後的區間進行規並,就是對二分後的區間再次合併起來,計算當前合併後區間的逆序對數。

else //如果a[i]>[j],說明a[i]大於目前右半邊區間最大的,則應將a[i]放入b陣列內,同時通過運用陣列下標計算出a[i]組成的逆序對數。

// cout<< sum

}void fenzhi(int l, int r)

int main()

fenzhi(1,n);

// for(int i=1; i<=n; i++)

//

// printf("\n");

cout<< sum << endl;

return 0;

}

code two(數列分治演示)

#includetypedef long long ll;

using namespace std;

const int n = 1e5+5;

int a[n], ans[n];

ll solve(int l, int r)

ll num = 0;//逆序對的個數

num += solve(l, mid);

num += solve(mid+1, r);

//合併子問題

//每一次的處理結果,公升序儲存在ans陣列

//將屬於不同子串行的逆序對個數累加

for(int i = l, j = mid+1, k = 0; i<=mid||j<=r; k ++)

}for(int i = 0; i <= (r-l); i ++)

a[l+i] = ans[i];

for(int i = 0; i <= r; i++)

printf("%d ", a[i]);

puts("");

cout << "num = " << num << " " << "return" << endl;

return num;

}int main()

遞迴與分治 歸併排序

描述 給定乙個數列,用歸併排序演算法把它排成公升序。輸入 第一行是乙個整數n n不大於10000 表示要排序的數的個數 下面一行是用空格隔開的n個整數。輸出 輸出排序後的數列,每個數字佔一行。輸入樣例 5 3 2 1 4 5 輸出樣例 1 2345 基本思路 歸併排序是將一組無序的數列,先一分為二,...

分治法與歸併排序

分解 將原問題分解成一系列子問題 解決 遞迴地求解各子問題。若子問題足夠小,則直接求解 合併 將子問題的結果合併成原問題的解。歸併排序 合併排序 歸併排序的關鍵在於歸併兩個相鄰的子串行,使其變成乙個排序好的新序列。如果這個新序列就是原來需要進行排序的陣列,那麼排序完成。所以,我們需要將原序列遞迴地分...

歸併排序(分治)

把乙個陣列 a 分成兩個部分 s,m m 1,e 假設兩部分分別有序,把這兩部分合併到另一陣列中 tmp 保證該陣列有序,然後再把資料 e s 1拷貝回陣列a 分治的原理。把資料無限二分,最後比較兩個數即可。遞迴實現。includeusing namespace std int a 10 int b...