ZSTU月赛—Problem C: 素数空间(哥德巴赫猜想+欧拉筛法)

ZSTU月赛—Problem C: 素数空间(哥德巴赫猜想+欧拉筛法)

Description
一天,小明正在搬砖,他收集了n(n<=1e7)种砖,砖的编号1-n这个时候,他突然说了一句,召唤神龙,然后,他穿越到了一个时空,发现这里的东西都是由素数组成的,这里的砖也和素数有关,他的砖也和他一块过来了,只是发生了一些变化,编号为1的砖不见了,编号为素数的砖没有发生变化,编号为合数的砖变成了编号为几块素数的砖(砖的编号和为之前的那个合数),由于这个世界能量太少,所以这些合数的砖尽可能的变成数目少的其他砖。于是小明想请教你他还有多少砖。

例如 编号为12的砖会变成编号5 7 的砖 不会变成编号2 3 2 2 3 的砖。编号9的砖会变成编号2 7 的砖 不会变成编号 3 3 3 的砖

Input
给你一个T(1<=T<=3e3)

接下来T行每行一个n(0<=n<=1e7)

Output
一共T行,每一行输出一个结果;

Sample Input
2
3
5
Sample Output
2
5

也算是通过这道题更加了解了哥德巴赫猜想,特别是三素数定理,顺便复习了一下欧拉筛法(后来试了下,其实普通筛素数也能过,代码就不贴了…)

题解:
哥德巴赫猜想:
大于二的偶数可以分解为两个素数之和;
大于七的奇数可以分解为三个素数之和;(是一定可以分解成三个素数之和,也有可能分解成两个) 分解成两个必然有一个是2,其他情况就是至少三个
多组测试要先用前缀和预处理一下。

#include<bits/stdc++.h>
#define fi first
#define se second
#define FOR(a) for(int i=0;i<a;i++)
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
using namespace std;
 
typedef long long ll;
typedef pair<int,int> P;
typedef pair<P,int> LP;
const ll inf=0x3f3f3f3f;
const int N=1e7+10;
const ll mod=998244353;
 
map<string,ll>  mp;
map<string ,int>ml;
 
 
int ans[N],prime[N];
bool did[N];
 
int n,m,x,t,tot=0;
 
int main()
{
    memset(did,0,sizeof did);
    int tot=0;
    for(int i=2;i<N;i++)
    {
        if(!did[i]) prime[++tot]=i,ans[i]=1;
        for(int j=1;j<=tot&&i*prime[j]<=N;j++)
        {
            did[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
    for(int i=2;i<=N;i++)
    {
        if(ans[i]) continue;
        ans[i]=2;
        if(i&1) ans[i]+=did[i-2];
    }
    for(int i=1;i<N;i++)
        ans[i]+=ans[i-1];
 
 
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d",&x);
        printf("%d\n",ans[x]);

    }
 
}
 
/**************************************************************
    Problem: 4403
    User: 2017329621071
    Language: C++
    Result: Accepted
    Time:200 ms
    Memory:89356 kb
****************************************************************/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值