2018 Multi-University Training Contest 2

时间:2023-03-08 17:49:49

题目链接:2018 Multi-University Training Contest 2

6318 Swaps and Inversions

题意:sum=x*逆序个数+交换次数*y,使sum最小

思路:反复观察发现,如果有逆序对,那么就一定有相邻的逆序对,而且交换他们一定是合理的

进一步发现,逆序对的数量即是最大交换的次数,最后,ans=min(x,y)*逆序个数

使用分治排序求逆序对个数:

#include<cstdio>
#include<iostream>
#include<set>
using namespace std;
const int maxn=1e5+10;
long long ans;
int num[maxn],num2[maxn]; void ins(int bg,int md,int ed)
{
int a=bg,b=md+1;
int now=bg;
while(a<=md&&b<=ed)
{
if(num[a]<=num[b])num2[now]=num[a],a++;
else num2[now]=num[b],b++,ans+=(md-a+1);
now++;
}
while(a<=md)num2[now++]=num[a++];
while(b<=ed)num2[now++]=num[b++];
for(int i=bg;i<=ed;i++)num[i]=num2[i];
} void mysort(int bg,int ed)
{
if(bg==ed)return;
int md=(bg+ed)/2;
mysort(bg,md);
mysort(md+1,ed);
ins(bg,md,ed);
} int main()
{
int n,a,b;
while(cin>>n>>a>>b)
{
ans=0;
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
mysort(1,n);
cout<<ans*min(a,b)<<endl;
}
return 0;
}