Educational Codeforces Round 20 C || Codeforces803C Maximal GCD (水题)

来源:互联网 发布:穿越火线自动开枪源码 编辑:程序博客网 时间:2024/06/05 06:31

题目链接:http://codeforces.com/contest/803/problem/C



题意: 给定一个n和k 输出一个长度为k的严格递增数列 使得他们的和等于n 切gcd最大  各项均大于0 如果不存在 输出-1

分析: 稍微想一想就可以得出 一个严格递增的数列gcd为x的话 那么每一项可以写作一个数乘x的形式 故这个数列的和n一定是x的倍数
            那么枚举n的因子 找到一个最大的因子就是这个数列的最大gcd 如果是枚举到1-sqrt(n)的话 要把i和n/i都放入因子数组中
            这个题感觉坑点很多 n和k都是1e10 以前一直判断阶和都是用一个for存到一个数组里的 然后有一次还奇葩用分块这样做过的
            然后这个题数组还开不了1e10 其实用高斯公式就好了  然后输出的数组长度也满足len*(len+1)/2<1e10 开个2e5的数组绝对够了
            好蠢 还是数学系的。。
            
            萌新代码写的发非常搓。。
#include<stdio.h>#include<algorithm>#include<cmath>using namespace std;long long int q[200005];long long int w[100005];int main(){long long int n,k;scanf("%lld%lld",&n,&k);if(k*(k+1)/2>n||k>200005)//比如这组数据1 4000000000 还是会爆ll 所以如果k>2e5直接就输出-1了 {printf("-1\n");return 0;}int x=0;    //因子个数 for(int i=1;i<=sqrt(n);i++)  //最开始用的i*i<n 但是i*i可能会大于int 然后re了一发 {if(n%i==0){x++;w[x]=i;x++;w[x]=n/i;      //比如24 2输出的8 16 gcd为8 >sqrt(24) }}sort(w+1,w+1+x);bool f=false;for(int i=1;i<=x;i++){long long int sum=k*(k-1)*w[i]/2;long long int ed=n-sum;     //前k-1个数为 i 2i 3i ....(k-1)i 最后一个数就为n-他们的和 if(ed>(k-1)*w[i]&&ed%w[i]==0)  //判断这个gcd为i的数列合法么 如果合法就跟新数组 {f=true;for(int j=1;j<=k-1;j++)q[j]=j*w[i];q[k]=ed;}else if(ed<=(k-1)*w[i])break;}if(f){for(int i=1;i<=k;i++){if(i!=k)printf("%lld ",q[i]);elseprintf("%lld\n",q[i]);}}elseprintf("-1\n");return 0;}

                                       

2 0