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;
}