Codeforces Codeforces Round #432 (Div. 2 D ) Arpa and a list of numbers
D. Arpa and a list of numbers
time limit per test 2 seconds
memory limit per test 256 megabytes
Arpa has found alist containingn numbers. Hecalls 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 performtwo 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 applythese operations to as many numbers as he wishes, and he is allowed to applythe second operation arbitrarily many times on the same number.
Help Arpa tofind the minimum possible cost to make the list good.
Input
First linecontains three integersn,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 linecontainsn integers a1, a2, ..., an (1 ≤ ai ≤ 106) — the elements of the list.
Output
Print a single integer: the minimumpossible 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,number1 must be deleted (with cost 23) and number 16 must increased by 1 (with cost 17).
Agcd (greatest common divisor) of a set of numbers is the maximum integer thatdivides all integers in the set. Read more about gcdhere.
【题意】
给出n个数,以及x,y。现在你可以对这n个数进行两种操作。
- 把任意一个数删除,花费为x。
- 把任意一个数加一,花费为y。
现在要求操作后所有数gcd不为1(不互质),求最小花费。
【思路】
显然可以想到去枚举gcd,考虑到时间上的优化,我们可以枚举素数,因为每个不为1的数一定是一个素数或者一个素数的倍数。(事实上直接暴力枚举gcd也能卡过)
素数用素筛预处理一下即可。
假设我们枚举的素数为prime。那么我们需要把所有数变为这个素数或其倍数或者将其中一个(或几个)删除。
显然如果我们要改变某个数的值,我们一定是增加到离它最近的是prime的倍数的那个数。所以我们应该提前预处理一下前缀和sum[i]、num[i],sum[i]表示小于等于i的数的和,num[i]表示小于等于i的数的个数,然后在区间内进行操作。
假设现在枚举的区间为【 k * prime[i] , (k+1) * prime[i]),那么我们先应该在区间内找一个分界点limit,一个数小于等于limit时删除它花费更少,否则把它一直加到k * prime[i]的花费更少。
limit可由x,y的大小得到。
limit=max( (j+1) * prime[i]-rate-1 , j * prime[i]);
然后就对区间里的数根据limit分成的两部分分别计算。
对于删除的那部分,计算方法为删除个数*x,即:
num[ limit ]-num[ j * prime[i]] * x
而对于加上的那部分,计算方法为(数的个数*加上后所得到的那个素数的倍数-原来的数的和) * y,即:
((num[(j+1) * prime[i]]-num[limit]) * ((j+1) * prime[i])-(sum[(j+1) * prime[i]]-sum[limit])) * y
然后不断更新最小值即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--) typedef long long ll;
const int maxn = *;
const ll mod = 1e9+;
const int INF = 0x3f3f3f3f;
const double eps = 1e-; int prime[maxn]= {};
int num_prime=;
bool isprime[maxn]= {,};
ll num[maxn],sum[maxn]; void init()
{
for(int i=;i<maxn;i++)
{
if(!isprime[i]) prime[num_prime++]=i;
for(int j=;j<num_prime&&i*prime[j]<maxn;j++)
{
isprime[i*prime[j]]=;
if(i%prime[j]==) break;
}
}
} int main()
{
int o;
int n,x,y;
init();
while(~scanf("%d%d%d",&n,&x,&y))
{
mst(num,);
mst(sum,);
int Max=;
for(int i=;i<n;i++)
{
scanf("%d",&o);
num[o]++;
sum[o]+=o;
Max=max(Max,o);
}
for(int i=;i<=Max*;i++) //预处理前缀和
{
num[i]+=num[i-];
sum[i]+=sum[i-];
}
int rate=x/y;
ll ans=1e18;
for(int i=;i<num_prime&&prime[i-]<=Max;i++)
{
ll cnt=;
for(int j=;j*prime[i]<=Max;j++)
{
int limit=max((j+)*prime[i]-rate-,j*prime[i]);
ll num1=num[limit]-num[j*prime[i]]; //删除
ll sum2=sum[(j+)*prime[i]]-sum[limit]; //加上
ll num2=num[(j+)*prime[i]]-num[limit];
cnt+=num1*x;
cnt+=(num2*((j+)*prime[i])-sum2)*y;
if(cnt>ans) break; //优化
}
ans=min(ans,cnt);
}
printf("%I64d\n",ans);
}
return ;
}
Codeforces Codeforces Round #432 (Div. 2 D ) Arpa and a list of numbers的更多相关文章
- Codeforces Round #432 (Div. 1) B. Arpa and a list of numbers
qtmd的复习pat,老子不想看了,还不如练几道cf 这题首先可以很容易想到讨论最后的共因子为素数 这个素数太多了,1-1e6之间的素数 复杂度爆炸 所以使用了前缀和,对于每个素数k的每个小区间 (k ...
- Codeforces Round #432 Div. 1 C. Arpa and a game with Mojtaba
首先容易想到,每种素数是独立的,相互sg就行了 对于一种素数来说,按照的朴素的mex没法做... 所以题解的简化就是数位化 多个数同时含有的满参数因子由于在博弈中一同变化的,让他们等于相当于,那么这样 ...
- Codeforces Beta Round #80 (Div. 2 Only)【ABCD】
Codeforces Beta Round #80 (Div. 2 Only) A Blackjack1 题意 一共52张扑克,A代表1或者11,2-10表示自己的数字,其他都表示10 现在你已经有一 ...
- Codeforces Beta Round #83 (Div. 1 Only)题解【ABCD】
Codeforces Beta Round #83 (Div. 1 Only) A. Dorm Water Supply 题意 给你一个n点m边的图,保证每个点的入度和出度最多为1 如果这个点入度为0 ...
- Codeforces Beta Round #79 (Div. 2 Only)
Codeforces Beta Round #79 (Div. 2 Only) http://codeforces.com/contest/102 A #include<bits/stdc++. ...
- Codeforces Beta Round #77 (Div. 2 Only)
Codeforces Beta Round #77 (Div. 2 Only) http://codeforces.com/contest/96 A #include<bits/stdc++.h ...
- Codeforces Beta Round #76 (Div. 2 Only)
Codeforces Beta Round #76 (Div. 2 Only) http://codeforces.com/contest/94 A #include<bits/stdc++.h ...
- Codeforces Beta Round #75 (Div. 2 Only)
Codeforces Beta Round #75 (Div. 2 Only) http://codeforces.com/contest/92 A #include<iostream> ...
- Codeforces Beta Round #74 (Div. 2 Only)
Codeforces Beta Round #74 (Div. 2 Only) http://codeforces.com/contest/90 A #include<iostream> ...
随机推荐
- H3C 模拟器 pc与sw直连 登录web
配置与上一节相同 开启web功能,并登录 [sw1]ip http enable [sw1]local-user admin New local user added. [sw1-luser-mana ...
- H3C 模拟器 pc与sw直连 开启telnet
如图所示 1 在pc上添加虚拟网卡,与上一章节的添加方式相同 配置pc的ip地址 10.17.4.3 255.255.252.0 2 sw设置 <sw1>system-view [sw1] ...
- JavaScript高程第三版笔记-函数表达式
1⃣️递归 阶乘函数: function factorial(num){ ){ ; } ); } } 改装一:(arguments.callee指向正在执行的函数的指针,实现解耦) function ...
- C语言基础:汉诺塔(递归方法)
分析:当只有一个盘子的时候,只需要从将A塔上的一个盘子移到C塔上.当A塔上有两个盘子是,先将A塔上的1号盘子(编号从上到下)移动到B塔上,再将A塔上的2号盘子移动的C塔上,最后将B塔上的小盘子移动到C ...
- Python简单网络爬虫实战—下载论文名称,作者信息(下)
在Python简单网络爬虫实战—下载论文名称,作者信息(上)中,学会了get到网页内容以及在谷歌浏览器找到了需要提取的内容的数据结构,接下来记录我是如何找到所有author和title的 1.从sou ...
- 【.NET】Browser Link: Failed to deserialize JSON in Browser Link call
问题 VS2013中调试程序发现,在浏览器控制台输出如下截图代码:
- Beego框架的一条神秘日志引发的思考
公司目前的后台是用Beego框架搭的,并且为了服务的不中断升级,我们开启了Beego的Grace模块,用于热升级支持.一切都跑井然有序,直到有一天,领导甩出一些服务日志,告知程序一直报错: 2018/ ...
- PJzhang:国外主流站点钓鱼网站示例工具shellphish
猫宁!!! 参考链接:https://www.uedbox.com/post/58583/ 这个是这个项目的github地址 https://github.com/thelinuxchoice/she ...
- 【转帖】网卡多队列技术与RSS功能介绍
网卡多队列技术与RSS功能介绍 2017年02月08日 15:44:37 Murphy_0806 阅读数 10665 标签: rss网卡dpdk 更多 个人分类: DPDK https://blog. ...
- MYSQL 优化--inner buffer 与关联查询变等值查询
转自:https://www.2cto.com/database/201312/262376.html 在数据库的应用中,我们经常需要对多表进行连表操作来获得关系型的数据,因此,应该更加的掌握好Mid ...