zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Overloaded的方法是否可以改变返回值的类型
    parseXXX的用法
    java的类型转换问题。int a = 123456;short b = (short)a;System.out.println(b);为什么结果是-7616?
    UVA 10405 Longest Common Subsequence(简单DP)
    POJ 1001 Exponentiation(大数处理)
    POJ 2318 TOYS(计算几何)(二分)
    POJ 1265 Area (计算几何)(Pick定理)
    POJ 3371 Flesch Reading Ease (模拟题)
    POJ 3687 Labeling Balls(拓扑序列)
    POJ 1094 Sorting It All Out(拓扑序列)
  • 原文地址:https://www.cnblogs.com/zmin/p/8884941.html
Copyright © 2011-2022 走看看