归并排序+逆序数模板

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int MAXN = 500100;
int n;
int a[MAXN]; //原始数组
int t[MAXN]; //临时数组
long long cnt=0;

void MergeSort(int *A, int L, int R, int *T)
{
    if(R - L > 1)
    {
        int M = L + (R - L) / 2; //这样写可以确保分界点总是靠近区间起点
        int p = L, q = M, i = L;
        MergeSort(A, L, M, T);
        MergeSort(A, M, R, T);
        while(p < M || q < R)
        {
            /* *p>=R说明此时右边部分已经全部进入临时数组,而左边还有剩余 *"||"后边那项说明左右均有剩余且左边最小值小于右边最小值   */
            if(q >= R || (p < M && A[p] <= A[q]))
            {
                T[i++] = A[p++];
            }
            else
            {
                T[i++] = A[q++];
                cnt+=M-p;  //此处记录的是逆序对的个数,记住cnt很可能是long long!!!!!
            }
        }
        for(i = L; i < R; i++)
        {
            A[i] = T[i];
        }
    }
}

int main()
{
    while(scanf("%d", &n)&&n)
    {
        memset(a,0,sizeof(a));
        memset(t,0,sizeof(t));
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &a[i]);
        }
        cnt = 0;
        MergeSort(a, 0, n, t); //左闭右开区间,注意别写错范围!
        for(int i = 0; i < n; i++)
        {
            printf("%d", a[i]);
            if(i == n - 1)
                putchar('\n');
            else
                putchar(' ');
        }
        printf("%lld\n", cnt);
    }
    return 0;
}

例题——POJ_2299_Ultra-QuickSort

Description
In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence
9 1 0 5 4 ,

Ultra-QuickSort produces the output
0 1 4 5 9 .

Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

Input
The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 – the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

Output
For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

Sample Input

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6
0

代码

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int MAXN = 500100;
int n;
int a[MAXN]; 
int t[MAXN];
long long cnt=0;

void MergeSort(int *A, int L, int R, int *T)
{
    if(R - L > 1)
    {
        int M = L + (R - L) / 2;
        int p = L, q = M, i = L;
        MergeSort(A, L, M, T);
        MergeSort(A, M, R, T);
        while(p < M || q < R)
        {
            if(q >= R || (p < M && A[p] <= A[q]))
            {
                T[i++] = A[p++];
            }
            else
            {
                T[i++] = A[q++];
                cnt+=M-p;
            }
        }
        for(i = L; i < R; i++)
        {
            A[i] = T[i];
        }
    }
}

int main()
{
    while(scanf("%d", &n)&&n)
    {
        memset(a,0,sizeof(a));
        memset(t,0,sizeof(t));
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &a[i]);
        }
        cnt=0;
        MergeSort(a, 0, n, t);
        printf("%lld\n",cnt);
    }
    return 0;
}

你可能感兴趣的:(归并排序+逆序数模板)