您的位置:首页 > 其它

2014多校第五场1001 || HDU 4911 Inversion (归并求逆序数)

2014-08-05 19:32 591 查看
题目链接

题意 : 给你一个数列,可以随意交换两相邻元素,交换次数不超过k次,让你找出i < j 且ai > aj的(i,j)的对数最小是多少对。

思路 : 一开始想的很多,各种都想了,后来终于想出来这根本就是求逆序数嘛,可以用归并排序,也可以用树状数组,不过我们用树状数组做错了,也不知道为什么。求出逆序数来再减掉k次,就可以求出最终结果来了。求逆序数链接1链接2

#include <stdio.h>

int left[250003], right[250003];
long long count;

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 main()
{
int n, i, a[500001];
long long k;

while (scanf("%d%I64d", &n,&k)!=EOF)
{
count = 0;
for (i=0; i<n; i++)
{
scanf("%d", &a[i]);
}
mergesort(a, 0, n-1);
count -=k;
if(count<0)count=0;
printf("%I64d\n",count );
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: