hust1347(归并排序求逆序对)

来源:互联网 发布:jquery ui.min.js 1.8 编辑:程序博客网 时间:2024/06/06 15:01

题意:

给出一个数列,你要对这个数列的数字进行k次交换操作,使得交换之后的数列逆序对虽少。


思路:

求原数列的逆序对,再和k比就行了。求逆序对要用归并排序,因为树状数组开不下。


代码:

#include<cstdio>#include<cstring>#include<climits>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<string>#include<queue>#include<map>#include<vector>#include<set>#include<sstream>using namespace std;long long _count;int _left[2500003], _right[2500003];void merge(int* a, int p, int q, int r){    int i, j, k, n1, n2;    n1 = q-p+1;    n2 = r-q;    for (i=0; i<n1; i++)    {        _left[i] = a[p+i];    }    for (i=0; i<n2; i++)    {        _right[i] = a[q+i+1];    }    _left[n1] = _right[n2] = 0x7fffffff;    i = j = 0;    for (k=p; k<=r; k++)    {        if (_left[i] <= _right[j])        {            a[k] = _left[i];            i++;        }        else        {            a[k] = _right[j];            j++;            _count += n1-i; /**此步骤是在归并排序法中加的一句,用来计数求逆序数的数目**/        }    }    return;}void mergesort(int* a, int p, int r){    int q;    if (p < r)    {        q = (p+r)/2;        mergesort(a, p, q);        mergesort(a, q+1, r);        merge(a, p, q, r);    }    return ;}int a[1000005];int main(){int n,m;int cas=1;while(EOF != scanf("%d %d",&n, &m) ) {_count=0;for(int i = 0; i < n; i++) {scanf("%d",&a[i]);}mergesort(a,0,n-1);int ans;_count-=m;int flag=0;for(int i=1;i<n;i++){if(a[i]==a[i-1]){flag=1;break;}}if(_count<0){_count=-_count;if(_count%2==0)ans=0;elseif(flag)ans=0;elseans=1;}elseans=_count;printf("Case #%d: %d\n",cas++,ans);}return 0;}


0 0
原创粉丝点击