Educational Codeforces Round 20 C. Maximal GCD (思维)

原题地址:http://codeforces.com/contest/803/problem/C

题意:构造一个长度为k的严格递增的数组数组,要求这k个数组的最大公约数尽可能的大,且这k个数的和为n

思路: 由于是严格递增的并且数据范围n最大只有1e10,所以我们可以简单计算一下,当k>1e6的时候,答案是一定不存在的.然后我们需要知道的一点是,所有数字之和是n,且要求gcd尽可能的大,那么gcd必定是n的约数,这样子,我们只需要枚举n的约数并判断是否可行就行了.

#include <bits/stdc++.h>
#include <cmath>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <set>
#include <map>
#include <cctype>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 1e6 + 5;
const int mod = 1e9 + 7;
ll n, k;
bool check(ll gcd) {
    ll sum = n;
    for (ll i = 1; i <= k; i++) {
        if (sum < i * gcd) return 0;
        sum -= i * gcd;
    }
    if (sum % gcd == 0) return 1;
    else return 0;
}
bool cmp(ll a, ll b) {
    return a > b;
}
int main() {
    scanf("%I64d%I64d", &n, &k);
    ull sum = (1 + k) * k / 2;
    if (sum > n || k > 1e6) {//注意如果不特判1e6,那么最后结果会乘爆ull
        printf("-1\n");
        return 0;
    }
    vector<ll>v;
    for (ll i = 1; i * i <= n; i++) {
        if (n % i == 0) {
            v.push_back(n / i);
            v.push_back(i);
        }
    }
    sort(v.begin(), v.end(), cmp);
    for (int i = 0; i < v.size(); i++) {
        int flag = check(v[i]);
        if (flag) {
            ll gcd = v[i];
            ll sum = 0;
            for (ll i = 1; i < k; i++) {
                printf("%I64d ", gcd * i);
                sum += i * gcd;
            }
            printf("%I64d\n", n - sum);
            return 0;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yiqzq/article/details/81747628