题解 CF45G 【Prime Problem】

MY(一名蒟蒻)

2021-03-21 12:55:52

题解

CF45G Prime Problem

构造好题。

构造题常规操作:对于某些不知道有没有可能无解的题,大胆猜测一定有解。不要上来就骗分输出无解。

接下来我们慢慢分析做法。

定义 sum 为这个数列的和。

分一组

最简单的情况。 sum 为质数。

那么用等差数列求和求出来之后直接判断一下即可。

分两组

引入哥德巴赫猜想。

好像已经证明了哥德巴赫猜想在某个挺大的范围内是正确的了,具体我也不太清楚。

我觉得是它一定是对的。

于是带着这种信念,枚举其中较小的质数,然后把它单独拎出来分一个组即可。

较小的质数一定小于 n我不会证明。

分三组

考虑让 $sum$ 变成偶数,由于最小的奇质数是 $3$ ,所以多分一组给 $3$ ,然后按照偶数情况处理。 --- 至此可以发现我们已经讨论完了所有情况,不存在无解的情况。 ```cpp #include <cstdio> #include <iostream> #include <algorithm> #include <cmath> using namespace std; int n,sum,ans[6010]; inline bool is_prime(int x) { if(x < 2) return false; for(int i=2;i*i<=x;i++) if(x%i == 0) return false; return true; } inline void draw(int x) { for(int i=2;i<=x>>1;i++) if(ans[i] == 1 && is_prime(i) && is_prime(x-i)) {ans[i]=2; return ;} } int main() { // freopen("work.in","r",stdin); freopen("work.out","w",stdout); scanf("%d",&n); sum=(n*(n+1))>>1; for(int i=1;i<=n;i++) ans[i]=1; if(!is_prime(sum)) { if(sum&1) { if(is_prime(sum-2)) ans[2]=2; else {ans[3]=3; draw(sum-3);} } else draw(sum); } for(int i=1;i<=n;i++) printf("%d ",ans[i]); // fclose(stdin); fclose(stdout); return 0; } ``` 线性筛没必要,实测根号暴力甚至更快。 ## $\text{Thank you for your reading!}

您的点赞和评论是对作者最大的支持!