SDUT 3317 反演 归并排序 求逆序数

反演

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

小鑫有一个数列a1, a2, ……,an可以交换两个相邻的数不超过k次。

 

求交换后最小的逆序对

 

Note:一个逆序对是存在一对(I, j)1 ≤ i < j ≤ n 且 a> aj 

输入

 

输入有多组,对于每组,第一行有两个数 n,k (1 ≤ n ≤ 100,000, 0 ≤ k ≤ 1,000,000,000

第二行有n个数a1,a2,…,an (0≤ai≤1,000,000,000)

输出

 

对于每一组输入,输出一个可能的最小的逆序对的数目。

示例输入

3 1
2 2 1
3 0
2 2 1

示例输出

1
2

提示

 

来源

 

示例程序

 
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<queue>

using namespace std;

int a[1000000],Arr[1000000];
long long int num=0;
int Sort(int low,int mid,int high)
{
    int i=low,j=mid+1,k=low;
    while(i<=mid&&j<=high)
    {
        if(a[i]>a[j])
        {
            Arr[k++]=a[j++];
            num+=j-k;
        }
        else
        {
            Arr[k++]=a[i++];
        }
    }
    while(i<=mid)
    {
        Arr[k++]=a[i++];
    }
    while(j<=high)
    {
        Arr[k++]=a[j++];
    }
    for(i=low; i<=high; i++)
    {
        a[i]=Arr[i];
    }
}
int MergeSort(int low,int high)
{
    if(low>=high)
        return 0;
    int mid=(low+high)/2;
    MergeSort(low,mid);
    MergeSort(mid+1,high);
    Sort(low,mid,high);
}
int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k))
    {
    	num=0;
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        MergeSort(1,n);
        if(num>=k)
			printf("%lld\n",num-k);
		else
			printf("0\n");
    }
}


你可能感兴趣的:(SDUT 3317 反演 归并排序 求逆序数)