NEFU 素数价值 (哥德巴赫猜想)

版权声明:转载注明下出处就行了。 https://blog.csdn.net/LJD201724114126/article/details/88959485

题目链接:哆啦A梦传送门

题解:

导论:

今日常见的猜想陈述为欧拉的版本,即任一大于2的偶数都可写成两个素数之和,亦称为“强哥德巴赫猜想”或“关于偶数的哥德巴赫猜想”。

从关于偶数哥德巴赫猜想,可推出:任一大于7的奇数都可写成三个质数之和的猜想。后者称为“弱哥德巴赫猜想”或“关于奇数的哥德巴赫猜想”。

我们证明下:任一大于7的奇数都可写成三个质数之和的猜想。当一个数为奇数时,我们是不是可以将它变为偶数(减去一个奇数),然后去满足欧拉的版本。那么此时最小的奇数(满足三个质数之和)就为2+2+3=7。证毕。

那么我们现在回到这题:

参考链接:

https://blog.csdn.net/ACdreamers/article/details/8575023

https://blog.csdn.net/weixin_43532890/article/details/83582924

当此数位偶数时,那么他的价值自然就是2了。

当一个数为奇数时:判断当前数是否为素数,如果是则价值为1,否则将此数减2(只有2为是偶数中的素数),判断减2后是否为素数,如果是价值为2。(我们也可以不减2,我们减3,那么此时数就变成偶数,价值就变为3了,但我们要价值最小,所以先判断减2的情况)

否则用这个数除以比他小的素数,当可以整除时,判断整除后的数是否为素数,是价值为2,否则价值为3,如果没有可整除的素数,那么这个数的价值为3.

#include<bits/stdc++.h>

using namespace std;

int tot,prime[50010];
bool vis[50010];

int ans[50010];

void init()
{
    int n=50002;
    for(int i=2;i<=n;i++)
    {
        if(!vis[i]){
            prime[++tot]=i;
            ans[i]=1; ///此数为素数
            ans[i+2]=2; ///这就相当于减2的情况
        }
        for(int j=1;j<=tot&&i*prime[j]<=n;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }

    for(int i=1;i<=tot;i++)
    {
        for(int j=1;j<=tot;j++)
        {
            int t=prime[i]*prime[j];
            if(t>n) break;
            ans[t]=2; ///这就是整除的情况,说明此数能整除一位素数

        }
    }


    ///偶数的价值都为2
    for(int i=4;i<=n;i+=2)
        ans[i]=2;

        ///其它大于7的奇数都可写成三个质数之和的猜想
    for(int i=2;i<=n;i++){
        if(!ans[i]) ans[i]=3;
    }

    
    ///统计前缀和
    for(int i=2;i<=n;i++)
    {
        ans[i]+=ans[i-1];
    }

}
int main()
{

    init();

    int ncase;
    scanf("%d",&ncase);

    while(ncase--)
    {
        int a,b;
        scanf("%d%d",&a,&b);

        printf("%d\n",ans[b]-ans[a-1]);
    }

    return 0;
}

做个有情怀的程序员。

猜你喜欢

转载自blog.csdn.net/LJD201724114126/article/details/88959485
今日推荐