• CodeForces


    You are given positive integer number n. You should create such strictly increasing sequence 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

    这题刚看一直以为数据有问题,1e10光输出就超时了啊
    但是经过思考可以发现,当k * (k + 1) / 2 > n 时,直接输出-1. 所以其实k的范围不到1e5

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

    解题思路:先解决数据范围的问题,我们设最大公约数为gcd,由严格递增可得,gcd取最小值为1,递增数组两数间的差取最小值1,则1 + 2 + 3 + …… + k <= n 否则就不存在,这样就缩小了数据范围

    接下来是求出这个数组,既然k个数都是gcd的倍数,那么n也是gcd的倍数,所以最终答案的gcd一定是n的因子,那么我们可以通过循环1到sqrt(n)暴力找出最大的因子即可。(如果不知道为什么1到sqrt(n)就能找出所有因子,可以去学学筛选素数法。

    附ac代码:
     1 #include<iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <string>
     7 typedef long long ll;
     8 using namespace std;
     9 const int maxn = 1e6;
    10 const int inf = 0x3f3f3f3f;
    11 int nu[maxn];
    12 int dis[maxn];
    13 using namespace std;
    14 int main()
    15 {
    16     ll n, k;
    17     scanf("%lld %lld", &n, &k);
    18 
    19     ll sum = k * (k + 1) / 2;
    20     if(k + 1 > n * 2/ k) {
    21         printf("-1");
    22         return 0;
    23     } else if(k == 1) {
    24         printf("%lld", n);
    25         return 0;
    26     }
    27     ll i = 0;
    28     ll u = 0;
    29     ll sqt = sqrt(n) + 1;
    30     ll gcd = 0;
    31     for(i = 1; i <= sqt; ++i) {
    32         if(n % i == 0) {
    33             if(i >= sum) {
    34                 gcd = n / i;
    35                 break;
    36             } else if(n / i >= sum) {
    37                 gcd = i;
    38             }
    39         }
    40     }
    41  //   printf("%lld i
    ", i);
    42     if(gcd == 0) printf("-1");
    43     else {
    44         for(ll j = 1; j <= k - 1; ++j) {
    45             printf("%lld ", gcd * j);
    46             n -= gcd * j;
    47         }
    48         printf("%lld", n);
    49     }
    50     return 0;
    51 }
    View Code
  • 相关阅读:
    再说LZ77压缩算法
    关于LZ77压缩算法
    Qt 简易设置透明按钮
    MFC edit 控件 自动将光标置于想要输入内容的位置
    事件和委托
    2016/06/07
    2016/04/28
    2016/4/27
    2016/04/26
    重载和重写(Overload, Override)
  • 原文地址:https://www.cnblogs.com/zmin/p/8884941.html
Copyright © 2020-2023  润新知