首页 > 代码库 > HDU 4911 Inversion (归并排序求逆序对)

HDU 4911 Inversion (归并排序求逆序对)

Inversion

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1898    Accepted Submission(s): 743


Problem Description
bobo has a sequence a1,a2,…,an. He is allowed to swap two adjacent numbers for no more than k times.

Find the minimum number of inversions after his swaps.

Note: The number of inversions is the number of pair (i,j) where 1≤i<j≤n and ai>aj.
 

Input
The input consists of several tests. For each tests:

The first line contains 2 integers n,k (1≤n≤105,0≤k≤109). The second line contains n integers a1,a2,…,an (0≤ai≤109).
 

Output
For each tests:

A single integer denotes the minimum number of inversions.
 

Sample Input
3 1 2 2 1 3 0 2 2 1
 

Sample Output
1 2
 
#include<iostream>
#include<string.h>
using namespace std;
#define MAX 100010
int aux[MAX];
int a[MAX];
int n;
long long k;
long long ans=0;
void merge(int a[],int l,int mid,int h){
    int i=l;
    int j=mid+1;
    for(int k=l;k<=h;++k){
        aux[k]=a[k];
    }
    for(int k=l;k<=h;k++){
        if(i>mid)a[k]=aux[j++];
        else if(j>h)a[k]=aux[i++];
        else if(aux[i]<=aux[j])a[k]=aux[i++];
        else
        {
            a[k]=aux[j++];
            ans+=(mid-i+1);
        }
    }
}
void mergesort(int a[],int l,int h){
    if(h<=l)return ;
    int mid=l+(h-l)/2;
    mergesort(a,l,mid);
    mergesort(a,mid+1,h);
    merge(a,l,mid,h);
}
int main(int argc, char *argv[])
{
    //freopen("4911.in","r",stdin);
    while(scanf("%d %lld",&n,&k)!=EOF){
        ans=0;
        memset(aux,0,sizeof(aux));
        for(int k=0;k<n;++k)
            scanf("%d",&a[k]);
        mergesort(a,0,n-1);
        if(k<ans)printf("%lld\n",ans-k);
        else
            printf("0\n");
    }
    return 0;
}

记得要把ans和k定义为long long


HDU 4911 Inversion (归并排序求逆序对)