Inversion
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1451 Accepted Submission(s): 591
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.
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).
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.
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 <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn=100100;
const int maxint= 999999999;
int a[maxn];
int lef[maxn];
int righ[maxn];
int n;
long long ans;
void sort(int l,int temp,int r)
{
int n1=temp-l+1;
int n2=r-temp;
for(int i=0;i<n1;i++)
lef[i]=a[i+l];
for(int i=0;i<n2;i++)
righ[i]=a[temp+i+1];
lef[n1]=righ[n2]=maxint;
int i=0;
int j=0;
for(int k=l;k<=r;k++)
{
if(lef[i]<=righ[j])
{
a[k]=lef[i];
i++;
}
else
{
a[k]=righ[j];
j++;
ans+=n1-i;//计算逆序数,在lef数组中有n1-i个比righ[j]大的
}
}
return;
}
void memsort(int l,int r)
{
int temp=(l+r)/2;
if(l<r)
{
memsort(l,temp);
memsort(temp+1,r);
sort(l,temp,r);
}
return;
}
int main()
{
int k;
while(~scanf("%d%d",&n,&k))
{
ans=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
memsort(0,n-1);//归并排序
if(ans-k<0)
ans=k;
printf("%I64d\n",ans-k);
}
return 0;
}