You are given positive integer number n. You should create such strictly increasingsequence of k positive numbers a1, a2, ..., ak, that their sum is equal to n and greatest common divisor is maximal.
Greatest common divisor of sequence is maximum of such numbers that every element of sequence is divisible by them.
If there is no possible sequence then output -1.
Input
The first line consists of two numbers n and k (1 ≤ n, k ≤ 1010).
Output
If the answer exists then output k numbers — resulting sequence. Otherwise output-1. If there are multiple answers, print any of them.
Examples
Input
6 3
Output
1 2 3
Input
8 2
Output
2 6
Input
5 3
Output
-1
题意:给定两个整数 n , k, 题目要求求一个 递增的序列,这个序列的个数为 k, 其和为 n, 这个序列的最大公约数还要最大。
一开始看见这个题懵了,感觉还挺难的(毕竟自己很菜 QAQ),然后想了一下,发现一个序列的最大公约数,和等差数列神似,就是首项呀(即是首项,也是公差),然后我就想了想,要不直接二分这个首项,判断一下前 k 项的和,最后输出 前 k - 1项,最后一项计算出来。。。然后几分钟写完,交了一发,,,成功的 WA on test 21。。。然后就一蹶不振,(开始摸鱼。。。
没办法,太菜了想不出来,于是开始日常搜题解,发现自己只想对了一半, 用那个二分的话,好像判断不了 n 因子的这个问题,因为最后一项就可能直接让整个序列的最大公因子为1。。。
然后就贴上正确思路:
对于这个序列,我们可以写成 即
, 要使 q 最大,前面的和最小即可。。而最小的情况就是 1 + 2 + 3 + ... + k , (因为题目明确说了严格递增),所以只需要枚举一下 判断一下 n 的因子(这样也能够保证最后一项 和前面时候一样的最大因子)。。。接下来的具体看
我抄袭的 代码:
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll n,k;
while(~scanf("%I64d %I64d",&n,&k)){
ll f = 2 * n / (k + 1); ///因为k可以达到10^10, 直接用 k * (k + 1) / 2, 这个式子是爆long long的,
if(k > f){ printf("-1\n"); continue; } ///原本比较的是 k * (k + 1) / 2 > n, 也就是变一下型
ll q = 0,s = (k + 1) * k / 2; ///很明显,s 就是 1 到 k 的和
for(int i = 1;i <= sqrt(n);i ++){
if(n % i == 0){
if(i >= s){ ///手画一下, 第一个 i >= s的,计算得到的 q 一定是最大的,
q = n / i; ///因为继续往后移, i 就增大了嘛, q 就相应的减小。
break;
}
else if(n / i >= s) ///如果 n / i >= s, 通过 i 依次计算得到的 n / i 是递减的,所以第一个 n / i ,q 不是最大
q = i;
}
}
if(!q){ printf("-1\n"); continue; }
ll sum = 0;
for(ll i = 1;i < k;i ++){
printf("%I64d ",i * q);
sum += i;
}
printf("%I64d\n",q * (n / q - sum));
}
return 0;
}
/// test 21
///3000000021 3
///3 6 3000000012