Educational Codeforces Round 20 C 數學

題目:

C. Maximal GCD
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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

求k個數(嚴格遞增),讓他們加起來等於n,且它們的最大公約數最大。  我假設最大公約數是maxDiv,因爲這幾個數是嚴格遞增的,所以它們的和最小sum=sigm(1...k);所以最大公約數不超過MAX=n/sum.    k1*g+k2*g+...kk*g=n,然後分解n,g一定是n的因數。k1+k2+..+kk=n/g。右分析可知n/g>=sum,我爲了方便,我讓k1=1*g,k2=2*g,k(k-1)=(k-1)*g,然後kk=n-sigma(1...k-1)。爲什麼這樣保證一定是遞增的?因爲n>=g*sigma(1...k)所以kk=n-g*sigma(1...k-1)>g*k的,故,kk大於(k1,k2,..k(k-1))。

code:

#include<cstdio>
#define max(a,b) (a>b?a:b)
typedef long long LL;
int main(void){
    LL n,k;scanf("%I64d%I64d",&n,&k);
    if(k>1000000){printf("-1\n");return 0;}
    LL sum=(1+k)*k/2;
    LL MAX=n/sum;
    int maxDiv=-1;
    for(LL i=1;i*i<=n;++i){
        if(n%i==0){
            if(i<=MAX)maxDiv=max(maxDiv,i);
            if(n/i<=MAX)maxDiv=max(maxDiv,n/i);
        }
    }
    if(maxDiv==-1){printf("-1\n");return 0;}
    for(LL i=1;i<=k-1;++i)
        printf("%I64d ",maxDiv*i);
    printf("%I64d\n",n-k*(k-1)/2*maxDiv);
}

另外就是我犯低級(要命)錯誤的兩個地方:


圖1會產生奇怪的答案,因爲maxDiv是int型

tu

圖1會導致死循環,i*i會變成負數

結論:涉及到溢出就用LL吧,0rzzzz

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章