Codeforces 432 Div. 2-D-Arpa and a list of numbers(枚举倍数求GCD)


题意:给你n个数,然后用两种操作使得这n个数的gcd不为1,每种操作有不同的成本,问你最小成本是多少

操作1:将这个数删除(花费为x)   操作2:将这个数加一(可以一直加,每加一次花费为y)

题解:昨晚总想着枚举因数,然后暴力求共约数,复杂度n*sqrt(m)  (m为数组中最大的数)

但是其中有很多问题,比如说有n-1个很大的质数,然后只有一个不是质数的话这方法是行不通吧,好吧

其实本来复杂度也是过不了关的,呢怎么办呢。。枚举gcd,然后暴力倍数。。。昨晚怎么不会搞23333

#include<set>  
#include<map>         
#include<stack>                
#include<queue>                
#include<vector>        
#include<string>      
#include<math.h>       
#include<stdio.h>                
#include<iostream>                
#include<string.h>                
#include<stdlib.h>        
#include<algorithm>       
#include<functional>        
using namespace std;
typedef __int64 ll;
#define inf 1000000000           
#define mod 1000000007                 
#define maxn  2000005     
#define PI 3.1415926  
#define lowbit(x) (x&-x)     
#define eps 1e-9   
ll a[maxn], b[maxn];
int main(void)
{
	ll ans;
	ll i, j, k, p, n, x, y, xx;
	scanf("%I64d%I64d%I64d", &n, &x, &y);
	for (i = 1;i <= n;i++)
	{
		scanf("%I64d", &xx);
		a[xx]++;b[xx] += xx;
	}
	for (i = 1;i <= 2000000;i++)
		a[i] += a[i - 1], b[i] += b[i - 1];
	p = x / y;ans = 100000000000000000;
	for (i = 2;i <= 1000000;i++)
	{
		ll tmp = 0;
		for (j = i;j <= 1000000 + i && tmp <= ans;j += i)
		{
			k = max(j - i + 1, j - p);
			tmp += ((a[j] - a[k - 1])*j - (b[j] - b[k - 1]))*y;
			tmp += (a[k - 1] - a[j - i])*x;
		}
		ans = min(ans, tmp);
	}
	printf("%I64d\n", ans);
	return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值