集训第四周(高效算法设计)A题 Ultra-QuickSort

原题poj 2299:http://poj.org/problem?id=2299

 

题意,给你一个数组,去统计它们的逆序数,由于题目中说道数组最长可达五十万,那么O(n^2)的排序算法就不要再想了,归并排序~~~

 

这里列出归并的解法:

#include"iostream"
using namespace std;

const int maxn=500000+10;

int T[maxn];
int a[maxn];

long long sum;

void merge_sort(int *a,int x,int y,int *T)
{
    if(y-x>1)
    {
        int m=x+(y-x)/2;
        int p=x,q=m,i=x;
        merge_sort(a,x,m,T);
        merge_sort(a,m,y,T);
        while(p<m||q<y)
        {
            if(q>=y||(p<m&&a[p]<a[q])) T[i++]=a[p++];
            else {sum+=m-p;T[i++]=a[q++];}
        }
        for(int i=x;i<y;i++) a[i]=T[i];
    }
}
int main()
{
    int n;
    while(cin>>n&&n)
    {
        sum=0;
        for(int i=0;i<n;i++) cin>>a[i];
        merge_sort(a,0,n,T);
     /*   for(int i=0;i<n;i++) cout<<a[i]<<' ';
        cout<<endl;*/
        cout<<sum<<endl;
    }
    return 0;
}

贴出一段代码,请找出其中的错误并改正:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=5e5+10;
int a[maxn],n;
int t[maxn];
long long ans;
void mergesort(int c[],int b,int e)
{
    if(e-b>1)
    {
    int p=(b+e)>>1;
    int mid=p,begi=b;
    mergesort(c,b,p);
    mergesort(c,p,e);

    int i=0;

    while(mid<e||begi<p)
    {
        if(mid>=e||(begi<p&&(c[begi]<=c[mid]))) t[i++]=c[begi++];
        else                                   {ans+=p-begi;t[i++]=c[mid++];}
    }

    i=0;
    for(int j=b;j<=e;j++) c[j]=t[i++];
    }
}

int main()
{
    while(scanf("%d",&n),n!=0)
    {
     for(int i=1;i<=n;i++) scanf("%d",&a[i]);

     ans=0;

     mergesort(a,1,n+1);

     printf("%d\n",ans);

    }
    return 0;
}
View Code

  改正后:

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=5e5+10;
int a[maxn],n;
int t[maxn];
long long ans;
void mergesort(int c[],int b,int e)
{
    if(e-b>1)
    {
    int p=(b+e)>>1;
    int mid=p,begi=b;
    mergesort(c,b,p);
    mergesort(c,p,e);

    int i=0;

    while(mid<e||begi<p)
    {
        if(mid>=e||(begi<p&&(c[begi]<c[mid]))) t[i++]=c[begi++]; /*必须严格递增,等于也算是逆序数,因为a[begi]后面的数肯定都会大于a[mid]*/
        else                                   {ans+=p-begi;t[i++]=c[mid++];}
    }

    i=0;
    for(int j=b;j<e;j++) c[j]=t[i++];  //j不会到e正如begi不会到mid
    }
}

int main()
{
    while(scanf("%d",&n),n!=0)
    {
     for(int i=1;i<=n;i++) scanf("%d",&a[i]);

     ans=0;

     mergesort(a,1,n+1);

     printf("%lld\n",ans); //输出长整型必须使用%lld或者%I64d

    }
    return 0;
}
View Code

 

 
posted @ 2015-08-05 11:11  江南何采莲  阅读(331)  评论(0编辑  收藏  举报