2018 Multi-University Training Contest 2

题目链接: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;
}

  

posted @ 2018-08-17 12:23  czh~  阅读(114)  评论(0编辑  收藏  举报