Codeforces Round #432 B. Arpa and a list of numbers

time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Arpa has found a list containing n numbers. He calls a list bad if and only if it is not empty and gcd (see notes section for more information) of numbers in the list is 1.

Arpa can perform two types of operations:

  • Choose a number and delete it with cost x.
  • Choose a number and increase it by 1 with cost y.

Arpa can apply these operations to as many numbers as he wishes, and he is allowed to apply the second operation arbitrarily many times on the same number.

Help Arpa to find the minimum possible cost to make the list good.

Input

First line contains three integers n, x and y (1 ≤ n ≤ 5·105, 1 ≤ x, y ≤ 109) — the number of elements in the list and the integers x and y.

Second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 106) — the elements of the list.

Output

Print a single integer: the minimum possible cost to make the list good.

Examples
Input
4 23 17
1 17 17 16
Output
40
Input
10 6 2
100 49 71 73 66 96 8 60 41 63
Output
10
Note

In example, number 1 must be deleted (with cost 23) and number 16 must increased by 1 (with cost 17).


這個題我居然錯了5次。全是1錯了一次,於是加了個if;超時了一次,把cin換成了scanf並且在if里加了等號。

這題的意思是,壞序列:非空且最大公約數爲1.我們可以對每個數執行兩種操作,加1或者刪除。可重複加1,每種操作分別花費a,b,現在在花費最小的情況下讓當前數組不是壞序列。

這題沒什麼巧的。兩重循環少不了。既然要讓最大公約數不爲1,那麼我們就從2開始到最大可能值一個一個試吧。如果當前最大公約數是2,那麼對每一個數選擇最優處理,加起來得到一個代價。對不同最大公約數的最小代價即爲所求。這裏我們考慮一次剪枝,如果所有不合格的數花費的最小代價依然沒有當前結果小,那麼就不用計算了。


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL maxn=1000086;
LL n,a,b;
LL val[maxn];
LL flag[maxn];
LL asd[maxn];
int main()
{
    cin>>n>>a>>b;
    memset(val,0,sizeof(val));
    memset(flag,0,sizeof(flag));
    LL mi = __INT64_MAX__ ;
    LL ma = 0;
    for(LL i=0;i<n;i++)
    {
        scanf("%d",&asd[i]);
        flag[asd[i]]++;
        if(asd[i]<mi&&asd[i]!=1)
            mi=asd[i];
        if(asd[i]>ma)
            ma=asd[i];
    }
    if(ma==1)
    {
        cout<< min(a,b)*n <<endl;
    }
    else{
        LL ans = __INT64_MAX__;
        for(LL i=2;i<=ma;i++)
        {
            if(val[i]) continue;
            LL tem = flag[i];
            for(LL j = i+i;j<=ma;j+=i)
            {
                val[j]=1;
                tem+=flag[j];
            }
            //這裏考慮一下剪枝
            if( (n-tem)*min(a,b) >= ans )    continue;
            LL ca=0;
            for(LL j=0;j<n;j++)
                 if(asd[j]%i)
                        ca+=(a>b*(i-asd[j]%i)) ? b*(i-asd[j]%i) : a;
            ans = min(ans,ca);
        }
        cout<<ans<<endl;
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章