原题地址: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;
}