HDU 4911 Inversion

Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u

Description

bobo has a sequence a 1,a 2,…,a n. 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 a i>a j.

Input

The input consists of several tests. For each tests: 

The first line contains 2 integers n,k (1≤n≤10 5,0≤k≤10 9). The second line contains n integers a 1,a 2,…,a n (0≤a i≤10 9).

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
/*
归并排序求逆序对对数,然后减去可以交换的次数
因为数据范围有10^9,所以逆序对的个数可能超过int类型
*/
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
int n;
long long k,ans;
int a[100005],b[100005];
void work(int l,int mid,int r)
{
    int i=l,j=mid+1;
    int len=0;
    while(i<=mid && j<=r)
    {
        if (a[i]>a[j])
        {
            b[++len]=a[j++];
            ans+=mid-i+1;
        } else b[++len]=a[i++];
    }
    while(i<=mid) b[++len]=a[i++];
    while(j<=r) b[++len]=a[j++];
    for(int i=1;i<=len;i++) a[l+i-1]=b[i];
}
void guibing(int l,int r)
{
    int mid;
    if (l>=r) return;
     mid=(l+r)/2;
     guibing(l,mid);
     guibing(mid+1,r);
     work(l,mid,r);
}
int main()
{
    while(~scanf("%d%lld",&n,&k))
    {
        ans=0;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        guibing(1,n);
        printf("%lld
",ans-k>0?ans-k:0);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/stepping/p/5815040.html