题意:给你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;
}
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/140468.html