归并排序

归并排序

模板

#include<iostream>

using namespace std;
    
const int N = 1e6 + 10;
int temp[N], q[N];

void merge_sort(int q[], int l, int  r)
{
    if(l >= r) return;
    // 递归
    int mid  = (l + r)  >> 1;
    merge_sort(q, l, mid);
    merge_sort(q, mid + 1, r);
    
    // 归并
    int i = l, j = mid + 1, k = 0;
    while(i <= mid && j <= r)
    {
        if(q[i] <= q[j]) temp[k ++] = q[i ++];
        else temp[k ++] = q[j ++];
    }
    
    while(i <= mid) temp[k ++] = q[i ++];
    while(j <= r) temp[k ++] = q[j ++];
    
    for(i = l, j = 0; i <= r; i ++, j ++)
    {
        q[i] = temp[j];
    }
}

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i ++) scanf("%d", &q[i]);
    
    merge_sort(q, 0, n - 1);
    
    for(int i = 0; i < n; i ++)
    {
        printf("%d ", q[i]);
    }
    return 0;
}

例题

逆序对

给定一个长度为 nn 的整数数列,请你计算数列中的逆序对的数量。

逆序对的定义如下:对于数列的第 ii 个和第 jj 个元素,如果满足 i<ji<j 且 a[i]>a[j]a[i]>a[j],则其为一个逆序对;否则不是。

输入格式

第一行包含整数 n,表示数列的长度。

第二行包含 n 个整数,表示整个数列。

输出格式

输出一个整数,表示逆序对的个数。

数据范围

\(1≤n≤1000001≤n≤100000\)
数列中的元素的取值范围 [1,\(10^9\)]。

输入样例:

6
2 3 4 5 6 1

输出样例:

5

代码

#include<iostream>

using namespace std;
    
const int N = 1e6 + 10;
int temp[N], q[N];
long long cnt = 0;

void merge_sort(int q[], int l, int  r)
{
    if(l >= r) return;
    // 递归
    int mid  = (l + r)  >> 1;
    merge_sort(q, l, mid);
    merge_sort(q, mid + 1, r);
    
    // 归并
    int i = l, j = mid + 1, k = 0;
    while(i <= mid && j <= r)
    {
        if(q[i] <= q[j]) temp[k ++] = q[i ++];
        else{
          temp[k ++] = q[j ++];
          cnt += mid - i + 1;
        } 
    }
    
    while(i <= mid) temp[k ++] = q[i ++];
    while(j <= r) temp[k ++] = q[j ++];
    
    for(i = l, j = 0; i <= r; i ++, j ++)
    {
        q[i] = temp[j];
    }
}

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i ++) scanf("%d", &q[i]);
    
    merge_sort(q, 0, n - 1);
    
    cout<< cnt;
    return 0;
}
posted @ 2022-02-04 16:36  我就一水  阅读(27)  评论(0)    收藏  举报