• Codeforces #432 Div2 D


    #432 Div2 D

    题意

    给出一些数字,如果这些数字的的 (gcd) 不为1则称这些数字 (good)
    可以有两种操作:

    1. 花费 x 删掉一个数
    2. 花费 y 将一个数加 1

    问使这些数 (good) 的最小花费。

    分析

    一直找不到这题的重点。其实仔细想想与 (gcd) 有关,或者说与一个数列所有数的 (gcd) 有关,应该考虑到枚举所有的因子(或素因子),枚举因子对于求一系列数的 (gcd) 时貌似是很常见的。
    对于本题,考虑枚举所有的素因子,设某个素因子为 (p),对于 ((j, j + p]) ((j=k*p,k in mathbb{Z},k geq 0)) 这个区间,考虑这个区间的哪些数应该被删掉,哪些数应该增加至 (j+p)
    (d) 表示区间内某数与区间右端点的差值,如果 (d*y>x) ,那么应该删去。
    (d=left lceil frac{x}{y} ight ceil),那么区间 ((j, j + p - d])里的数应该被删去,((j+p-d, j + p])里的数增加至 (j+p)

    可以通过预处理出的前缀和以及数字出现次数的前缀和来高效的计算出答案。

    code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN = 1e6 + 10;
    int a[MAXN];
    ll s[MAXN], sum[MAXN];
    int notprime[MAXN];
    vector<int> prime;
    
    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        for(int i = 2; i < MAXN; i++) if(!notprime[i]) {
            prime.push_back(i);
            for(ll j = 1LL * i * i; j < MAXN; j += i) notprime[j] = 1;
        }
        int n, x, y;
        cin >> n >> x >> y;
        for(int i = 0; i < n; i++) {
            cin >> a[i];
            s[a[i]]++;
        }
        for(int i = 1; i < MAXN; i++) {
            sum[i] = sum[i - 1] + s[i] * i;
            s[i] += s[i - 1];
        }
        ll ans = 1e18;
        int d = ceil(1.0 * x / y);
        for(int p : prime) {
            ll res = 0;
            for(int j = 0; j < MAXN; j += p) {
                if(p <= d) {
                    res += ((s[min(MAXN - 1, j + p)] - s[j]) * (j + p) - (sum[min(MAXN - 1, j + p)] - sum[j])) * y;
                } else {
                    res += (s[min(MAXN - 1, j + p - d)] - s[j]) * x;
                    if(j + p - d + 1 > MAXN) break;
                    res += ((s[min(MAXN - 1, j + p)] - s[j + p - d]) * (j + p) - (sum[min(MAXN - 1, j + p)] - sum[j + p - d])) * y;
                }
            }
            ans = min(ans, res);
        }
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    MyBatis中Like语句使用总结
    使用dom4j解析xml为json对象
    实体类里布尔类型在数据库里可以用整型映射
    Java枚举根据key获取value
    Oracle和Mysql中mybatis模糊匹配查询区别
    解决3 字节的 UTF-8 序列的字节 3 无效
    git上传代码到github
    OpenShift 3.11离线环境的jenkins演示
    OpenShift下的JVM监控
    OpenShift 4.1 演示
  • 原文地址:https://www.cnblogs.com/ftae/p/7524130.html
Copyright © 2020-2023  润新知