题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=6318
分析:
我们注意到逆序对=交换相邻需要交换的次数,那么输出:min(x,y)×逆序对个数
如何计算逆序对个数可以参考一下我的另一篇博客:求序列的逆序数
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[100010];
int b[100010];
void Merge(int a[],int s,int m,int e,int b[])
{
int pb = 0;
int p1 = s,p2 = m+1;
while(p1<=m && p2<=e)
{
if(a[p1] > a[p2])
b[pb++] = a[p1++];
else
b[pb++] = a[p2++];
}
while(p1<=m)
b[pb++] = a[p1++];
while(p2<=e)
b[pb++] = a[p2++];
for(int i = 0;i < e-s+1;i++)
a[s+i] = b[i];
}
long long Count(int a[],int s,int m,int e)
{
long long res = 0;
int p1 = s;
int p2 = m+1;
while(p1<=m && p2<=e)
{
if(a[p1] > a[p2])
{
res += (e-p2+1);
p1++;
}
else
p2++;
}
return res;
}
long long MergeSort_Res(int a[],int s,int e,int b[])
{
long long res = 0;
if(s < e)
{
int m = s + (e-s)/2;
res += MergeSort_Res(a,s,m,b);
res += MergeSort_Res(a,m+1,e,b);
res += Count(a,s,m,e);
Merge(a,s,m,e,b);
}
return res;
}
int main()
{
int n,x,y;
while(~scanf("%d %d %d",&n,&x,&y))
{
for(int i = 0;i < n;i++)
scanf("%d",&a[i]);
printf("%lld\n",MergeSort_Res(a,0,n-1,b)*min(x,y));
}
return 0;
}