On the ideological divide and conquer and merge

Merge sort

To understand the idea of ​​merging, merge sort of understanding can not be separated, the former look at the code puzzling, then see a picture suddenly realized that, under the laws:

Comparison of two arrays each note can be two different sections of an array, each time a smaller number stored in a temporary array, thus completing the merge sort. Of course, if both arrays are ordered, then the question is how to make these two arrays are ordered it, which uses recursion.

    merge_sort(left, mid);
    merge_sort(mid+1, right);

Why use recursion to achieve it, look at the next picture.

example

If only that theory becomes bitter and difficult, posted a topic from the following Rockwell Valley, small test their skills.
https://www.luogu.org/problem/P1908
detailed explanation has been marked in code comments

#include<bits/stdc++.h>
using namespace std;
int N;
int a[100000+10], temp[100000+10];
long long ans = 0;          //ans用于记录逆序对的数量
void merge_sort(int l, int r)
{
    if(l == r) return ;
    int k = 0 ,mid = (l + r)/2;
    merge_sort(l, mid);             
    merge_sort(mid+1, r);
    //注意一定要先递归,这样就可以保证l ~ mid区间、mid + 1 ~ r区间已经完成了从小到大的排序
    int i = l, j = mid + 1;
    while(i <= mid && j <= r)
    {
        if(a[i] < a[j])
            temp[k++] = a[i++];       //将较小的数字存储在临时数组中
        else 
        {
            temp[k++] = a[j++];
            ans += mid - i + 1;     //因为a[i]-a[mid]按递增顺序排列 所以a[j]之前有mid-i+1对逆序对

        }
    }
    while(i <= mid)         //如果a[i...mid]有剩余
        temp[k++] = a[i++];     
    while(j <= r)           //如果a[j...r]有剩余
        temp[k++] = a[j++];
    for(k = 0; k <= (r - l); k++)
        a[l + k] = temp[k];         //这里就完成了两块区间的有序归并

}
int main()
{
    std::ios::sync_with_stdio(false);
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    cin >> N;
    memset(a, 0, sizeof(a));
    memset(temp, 0, sizeof(temp));
    for(int i = 0; i < N; i++)
        cin >> a[i];
    merge_sort(0, N-1);
    cout << ans << endl;
}

Reference blog: https://www.cnblogs.com/mrblug/p/5763138.html

Guess you like

Origin www.cnblogs.com/KeepZ/p/11319204.html