[CF803C] Maximal GCD(gcd,贪心,构造)

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

题意:k个单增的数和为n,求这k个数gcd最大。

很好特判的一点是∑i,i from 1 to k如果大于n的话,很明显是不能构造的。所以特判一发,结果k*(k+1)/2爆LONG LONG TLE了一发QAQ。

设a1 a2 ... ak为解,那么a1+a2+...+ak=n,设gcd(a1,a2...,ak)=p,那么a1=p*b1,a2=p*b2...ak=p*bk。

那么gcd(b1,b2,...,bk)=1。且p*(b1+b2+...+bk)=n,那么n%p=0,说明他们的gcd p为n的因数。

首先处理出所有n的因数。

这样有一个很o_O的构造,反正b1 b2他们的gcd是1,不如让他们从头到尾开始排,前k-1个分别是1~k-1,因为不能重复,则特判第k项是否大于k-1就行了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 LL n, k;
 6 vector<LL> p;
 7 
 8 bool ok(LL v) {
 9     LL m = n / v;
10     LL sum = (1 + (k - 1)) * (k - 1) / 2;
11     if(m - sum >= k) {
12         for(LL i = 1; i < k; i++) printf("%I64d ", i * v);
13         printf("%I64d
", v * (m - sum));
14         return 1;
15     }
16     return 0;
17 }
18 
19 int main() {
20     // freopen("in", "r", stdin);
21     while(~scanf("%I64d%I64d",&n,&k)) {
22         if(k+1 > 2 * n / k) {
23             puts("-1");
24             continue;
25         }
26         p.clear();
27         for(LL i = 1; i*i <= n; i++) {
28             if(n % i == 0) {
29                 p.push_back(i);
30                 p.push_back(n/i);
31             }
32         }
33         sort(p.begin(), p.end());
34         p.erase(unique(p.begin(), p.end()), p.end());
35         bool flag = 0;
36         for(int i = p.size() - 1; i >= 0; i--) {
37             if(ok(p[i])) {
38                 flag = 1;
39                 break;
40             }
41         }
42         if(!flag) puts("-1");
43     }
44     return 0;
45 }
原文地址:https://www.cnblogs.com/kirai/p/6842685.html