Maximal GCD CodeForces - 803C (数论+思维优化)

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 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

Copy

6 3

output

Copy

1 2 3

input

Copy

8 2

output

Copy

2 6

input

Copy

5 3

output

Copy

-1

题目链接:https://vjudge.net/problem/CodeForces-803C#author=0一题目大意:给你一个N和K,让你输出K个数,使其K个数的和为N,并且这K个数是严格递增的,同时要求这K个数的gcd尽可能的大。思路:首先我们要用思维优化一下:通过观察数据范围,我们可以看到K最值可以取到1e10,那么题目又要输出K个数,光输出K个数的时间复杂度就是O(K)了,题目要求1000ms,肯定会TLE。那么我们应该知道肯定当K大于一个数值的时候,就不存在答案输出-1了。由于要求这K个数是严格递增的,那么不难想到,当gcd最小为1的时候,也是1,2,3,5,6,,..,k。那么这K个数的总和就是(K*(1+K))/2,(等差数列的公式),即如果这个数大于N的时候,是无解的输出-1,那么根据N最大可以取到1e10,我们可以算出K的最值应该是141420,当K>141420的时候,直接输出-1表示无解。原因上边已经论述,这时候的总和是大于1e10的,即大于N的值。然后我们进行有解的情况。首先要使K个数和为N,并且GCD尽可能的大, 我们应该可以得知这样一个信息,这个GCD一定是N的一个因子(因为K个数都可以被gcd整除,那么他的和也一定被gcd整除)这样我们首先O(sqrt(N))的时间里求出N的所有因子,然后从大到小排序(贪心的思想,因为题目要求gcd尽量大)。并且只有当n/gcd >= ((K*(1+K))/2) 的时候,才会构造出以gcd为a1值公差为gcd的等差数列。

然后我们就只需要用代码实现出这个过程就好了。(本文原文出处:https://www.cnblogs.com/qieqiemin/)我的AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb std::ios::sync_with_stdio(false)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), ‘\0‘, sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define gg(x) getInt(&x)
using namespace std;
typedef long long ll;
inline void getInt(int* p);
const int maxn=1000010;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
ll n,k;
vector<ll> foc;
int main()
{
//    gbtb;
//    cin>>n>>k;
    scanf("%lld %lld",&n,&k);
    ll sum=(k*(1ll+k)/2ll);
    if(sum>n||k>=141421ll)
    {
//        cout<<-1<<‘\n‘;
        printf("-1\n");
    }else
    {
        if(k==1ll)
        {
//            cout<<n<<‘\n‘;
            printf("%lld\n",n);
        }else
        {
            int num;
            ll js=sqrt(n);
            for(ll i=1ll;i<=js;i++)
            {
                if(n%i==0)
                {
                    foc.push_back(i);
                    if(i*i!=n)
                    {
                        foc.push_back(n/i);
                    }
                }
            }
            sort(foc.begin(),foc.end());
            reverse(foc.begin(),foc.end());
            ll gcd;
            num=foc.size();
            for(int j=0;j<num;j++)
            {
                ll i=foc[j];
                if(n%i==0)
                {
                    ll cnt=n/i;
                    if(cnt>=sum)
                    {
                        gcd=i;
                        break;
                    }
                }
            }
            ll now=gcd;
            ll he=0ll;
            for(ll i=1ll;i<=k-1;i++)
            {
                he+=now;
                printf("%lld ",now);
                now+=gcd;
            }
            printf("%lld ",n-he);
        }
    }
    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch == ‘ ‘ || ch == ‘\n‘);
    if (ch == ‘-‘) {
        *p = -(getchar() - ‘0‘);
        while ((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) {
            *p = *p * 10 - ch + ‘0‘;
        }
    }
    else {
        *p = ch - ‘0‘;
        while ((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) {
            *p = *p * 10 + ch - ‘0‘;
        }
    }
}

 

原文地址:https://www.cnblogs.com/qieqiemin/p/10241573.html

时间: 2024-08-06 22:10:22

Maximal GCD CodeForces - 803C (数论+思维优化)的相关文章

UVA 11426 - GCD - Extreme (II) (数论)

UVA 11426 - GCD - Extreme (II) 题目链接 题意:给定N,求∑i<=ni=1∑j<nj=1gcd(i,j)的值. 思路:lrj白书上的例题,设f(n) = gcd(1, n) + gcd(2, n) + ... + gcd(n - 1, n).这样的话,就可以得到递推式S(n) = f(2) + f(3) + ... + f(n) ==> S(n) = S(n - 1) + f(n);. 这样问题变成如何求f(n).设g(n, i),表示满足gcd(x, n)

HDU4497 GCD and LCM 数论 素数分解

题意很简单首先以前做最简单的LCM跟CGD的时候都知道先求出两个数A,B的最大公约数GCD,那么LCM可以利用  A*B/GCD来求得,这点一开始脑残了没想到,结果没有进行特盘所以错了,意思就是 题目给的L%G不为0的话就是无解,结果我给判其它的去了,肯定漏了些什么没有发现 然后对于 L/G进行素因子分解,同时任意的数都能够通过素因子分解来表示,所以三个解x,y,z也能分解 L/G = p1^q1*p2^q2.... x = p1^i1*... y = p1^j1*... z = p1^k1*.

Trailing Loves (or L&#39;oeufs?) CodeForces - 1114C (数论)

大意: 求n!在b进制下末尾0的个数 等价于求n!中有多少因子b, 素数分解一下, 再对求出所有素数的最小因子数就好了 ll n, b; vector<pli> A, res; void factor(ll x) { int mx = sqrt(x+0.5); REP(i,2,mx) if (x%i==0) { int t = 0; while (x%i==0) x/=i,++t; A.pb(pli(i,t)); } if (x>1) A.pb(pli(x,1)); } int main

Codeforces Round #410 (Div. 2)C. Mike and gcd problem(数论)

传送门 Description Mike has a sequence A = [a1, a2, ..., an] of length n. He considers the sequence B = [b1, b2, ..., bn] beautiful if the gcd of all its elements is bigger than 1, i.e. . Mike wants to change his sequence in order to make it beautiful.

CF803C Maximal GCD (思维)

??   写在纸上了 1 #include<bits/stdc++.h> 2 #define mem(a) memset(a,0,sizeof(a)) 3 #define mem1(a) memset(a,-1,sizeof(a)) 4 #define ll long long 5 #define mp make_pair 6 #define inf 0x3f3f3f3f 7 const int N=1e6+5; 8 const int M=1e3+10; 9 const ll lim=1e1

CodeForces 300C --数论

A - A Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 300C Description Vitaly is a very weird man. He's got two favorite digits a and b. Vitaly calls a positive integer good, if the deci

CodeForces 396A 数论 组合数学

题目:http://codeforces.com/contest/396/problem/A 好久没做数论的东西了,一个获取素数的预处理跟素因子分解写错了,哭瞎了,呵呵, 首先ai最大值为10^9,n为500,最坏的情况 m最大值为500个10^9相乘,肯定不能获取m了,首选每一个ai肯定是m的一个因子,然后能分解就把ai给分解素因子,这样全部的ai都分解了  就能得到m的 所有素因子 以及 所有素因子的个数,题目求的 是n个因子的 不同序列的个数,所以每次 只能选出n个因子,这n个因子由素因子

Codeforces 833B 线段树优化 dp

Codeforces  833B  The Bakery 题意: n 个数要分成 k 块,每块的价值是其不同数的个数,问价值和最大是多少. tags: dp[i][j]表示前 j 个数分成 i 块的最大权值和,转移: dp[i][j] = max( dp[i-1][k] + val[k+1][j] ) , k是 1~j . 但这个过程其实并不好转移,要利用累加的特点,用线段树进行优化 (感觉我不看题解是想不到的,2333) 大概就是,对于第 i 层,我们假定已经知道了第 i-1 层,也就是求出了

CodeForces 359D (数论+二分+ST算法)

题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=47319 题目大意:给定一个序列,要求确定一个子序列,①使得该子序列中所有值都能被其中一个值整除,②且子序列范围尽可能大(r-l尽可能大). 解题思路: 对于要求1,不难发现只有min(L,R)=gcd(L,R)时才行.其中gcd是L,R范围内的最大公约数,min是L,R范围内的最小值. 对于要求2,传统思路是r-l从大到小枚举,每次确定一个(L,R)范围,进行判