【枚举gcd】CF803 C

62 篇文章 0 订阅

Problem - C - Codeforces

题意:

思路:

要使所有数的 gcd 尽可能大

设 gcd = k

那么就是 k1 * k,k2 * k,k3 * k,....

它们的和是n

那么(k1 + k2 + k3 +....) * k = n

根据惯用套路,我们去枚举 n 的因子即可

因为要求严格递增,贪心地考虑,构造成1,2,3,....,k - 1即可

然后最后一项就是 n - k * (k - 1) / 2

需要判断最后一项要大于k - 1

注意 gcd = 1和 gcd = n的情况要特判,不然枚举因子的时候会超时

还有就是,(2 * n) / k < 1 + k) 的情况直接判无解,否则会超时

Code:

#include <bits/stdc++.h>

using i64 = long long;

const int N = 2e5 + 10;

i64 n, k;

void solve() {
    std::cin >> n >> k;

    if((2 * n) / k < 1 + k) {
		std::cout << -1 << "\n";
		return;
	}
    std::vector<int> V;
    for (int i = 2; i <= n / i ; i ++) {
        if (n % i == 0) {
            V.push_back(i);
            if (i != n / i) V.push_back(n / i);
        }
    }
    
    std::sort(V.begin(), V.end());

    bool ok = false;
    //特判gcd == n
    if (k == 1) {
        ok = true;
        std::cout << n << "\n";
        return;
    }
    //gcd在1到n之间
    for (int i = V.size() - 1; i >= 0; i --) {
        int d = V[i];
        int sum = n / d;
        if (sum - k * (k - 1) / 2 <= k - 1) continue;
        ok = true;
        for (int i = 1; i <= k - 1; i ++) {
            std::cout << i * d << " "; 
        }
        std::cout << ((n / d) - (k * (k - 1) / 2)) * d << "\n";
        break;
    }

    //特判gcd == 1
    if ((n - k * (k - 1) / 2) > k - 1 && ok == false) {
        ok = true;
        for (int i = 1; i <= k - 1; i ++) std::cout << i << " ";
        std::cout << n - k * (k - 1) / 2 << "\n";
    }
    if (ok == false) {
        std::cout << -1 << "\n";
    }
}
signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int t = 1;
    
    while (t--) {
        solve();
    }
    
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值