递归和分治:poj2299

/*

总体思想使用分治法,进行归并排序,求出每次合并的逆序总数累加。说明一下:按照算导中方法写的程序

有可能会超时,因为每次merge都重新分配两个数组,且需单独循环计算逆序,操作较多。另外,最后结果sum使用long long,

在最坏情况下是n^2级的,n<500000,一个long(4B,2^32) 不够 。 3692K
375MS

*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

const int N = 500005;

long long sum;

int vec[N],back[N];

void merge(int s,int m,int e){

    int i = s, j = m + 1, k = s;

    while (i <= m && j <= e) {

        if (vec[i] > vec[j]) {

            sum += m – i + 1;   //逆序数累加 

            back[k++] = vec[j++];

        } else {

            back[k++] = vec[i++];

        }

    }

    while (i <= m)

        back[k++] = vec[i++];

    while (j <= e)

        back[k++] = vec[j++];

    memcpy(vec + s, back + s, sizeof(*back) * (e – s + 1));

}

void merge_sort(int p,int r){

    if (p<r){

        int q=(p+r)/2;

        merge_sort(p,q);

        merge_sort(q+1,r);

        merge(p,q,r);

    }

}      

int main(){

    int i,n;

    scanf(“%d”,&n);

    while(n!=0){

        sum = 0;

        for(i=1;i<=n;i++){

            scanf(“%d”,vec+i);

        }

        merge_sort(1,n);

        printf(“%lld\n”,sum);

        scanf(“%d”,&n);

    }

    return 0;

}

    原文作者:递归与分治算法
    原文地址: https://blog.csdn.net/kimili1987/article/details/7287386
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞