CodeForces - 803C Maximal GCD(构造 + 思维!)

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 * (a_{1} + a_{2} + ... + a_{k}) = n 即 a_{1} + a_{2} + ... +a_{k} = \frac{n}{q},  要使 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

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值