欧拉筛法求素数个数

判断a是否为素数,求1——n的素数个数

考虑欧拉筛法————

  http://wenku.baidu.com/link?url=dFs00TAw8_k46aeSbXy5nB5LVqJ51uUJgY9zVWEDQdwjLN-qLFWZuYcGPE5EDcztNQAMtKfUbSseBvfBzV4fcQvlneOVHJJQvgJjcGC1iN7

//判断是否为素数;计算1到n的素数个数
#include<iostream>
#include<cstring>
#define MAX 10000000
using namespace std;
bool b[MAX+1];   //b中0表示为质数,1表示为非质数
int c[MAX+1];
int sushu(int n){
    memset(b, 0, n + 1);
    b[0]=1;
    b[1]=1;     //1既非素数也非合数
    int i, j, cnt = 0, t;
    for (i = 2; i <= n; i++){
        if (!b[i]){
            c[cnt++] = i;
        }
        for (j = 0; j<cnt; j++){
            t = i*c[j];  //质数乘质数为合数,质数乘合数为合数,一个合数必可写成质数乘一个数的形式
            if (t > n)
                break;
            b[t] = true;
            if (i%c[j] == 0)
                break;
        }
    }
    return cnt;
}

int main()
{
    int T,a,n,c;
    cin>>T;
    while(T--)
    {
        cin>>a>>n;
        c=sushu(n);
        if(b[a]==0)
            cout<<"YES "<<c<<endl;
        else
            cout<<"NO "<<c<<endl;
    }
    return 0;
}

看看别人的代码,10亿秒了,,

#include<iostream>
#include<cstring>
#include<cstdio>
#include<ctime>
#include<algorithm>
using namespace std;
int n=11000000;
bool visit[11000000];
int  prime[11000000];

void init_prim()
{
    memset(visit, true, sizeof(visit));
    visit[0] = visit[1] = false;
    int num = 0;
    for (int i = 2; i <= n; ++i)
    {
        if (visit[i] == true)
        {
            num++;
            prime[num] = i;
        }
        /*for (int j = 1; ((j <= num) && (i * prime[j] <= n));  ++j)
        {
            visit[i * prime[j]] = false;
            if (i % prime[j] == 0) break;
        }*/
        for(int j = 2 ;  i *j <=n; j++)
        {
          visit[i * j] = false;
        }
    }
}

int OutNum(int n)
{
    int i;
    for(i=1;prime[i]<=n;i++);
        return i-1;
}

int main()
{
    clock_t start, finish;
    double  duration;
    start = clock();
    init_prim();
    int T;
    cin >> T;
    while(T--)
    {
        int x,n;
        cin >> x >> n;
        if(visit[x])
            cout << "YES" << " ";
        else
            cout << "NO" << " ";

        cout << OutNum(n) << endl;
    }
    finish = clock();
    duration = (double)(finish - start) / CLOCKS_PER_SEC*1000.0;
    printf( "%f ms\n", duration );
    return 0;
} 
时间: 2024-10-17 06:21:19

欧拉筛法求素数个数的相关文章

欧拉筛法求素数

欧拉筛法求素数     首先,我们知道当一个数为素数的时候,它的倍数肯定不是素数.所以我们可以从2开始通过乘积筛掉所有的合数.     将所有合数标记,保证不被重复筛除,时间复杂度为O(n).代码比较简单↓_↓ /*求小于等于n的素数的个数*/ #include<stdio.h> #include<string.h> using namespace std; int main() { int n, cnt = 0; int prime[100001];//存素数 bool vis[

线性筛法(欧拉筛法)求素数

写$\text{O}\left( n \log{\log{n}}\right)$的筛法很长时间了,我却从来没想过它的优化.偶然间看到线性筛法,心想大约是不错的优化,于是便爬去学习下. 首先,$\text{O}\left( n \log{\log{n}}\right)$的筛法肯定要比$\text{O}\left( n\right)$的慢,虽然在现在的机子上不明显.还是不要将$\text{O}\left( n \log{\log{n}}\right)$比较靠谱.但是线性筛法有着它自己的用途.

弄了个欧拉筛求素数

最近遇到某方面的内容和欧拉筛有关系,于是就自己重新弄了个欧拉筛,当然记得以前自己曾经写过一次,这次自己完全写起来发现和第一次写的主体方面还是差不多(就那么一个细微的区别),可以参考一下 程序代码: #include<stdio.h>#include<stdlib.h>#include<string.h>#include<assert.h> void nodeMal( void** ,size_t );void nodeFree( void** );void 

NEFU 2 - 猜想 - [筛法求素数]

题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=2 Time Limit:3000ms Memory Limit:65536K Description 哥德巴赫(Goldbach ]C.,1690.3.18~1764.11.20)是德国数学家:出生于格奥尼格斯别尔格(现名加里宁城):曾在英国牛津大学学习:原学法学,由于在欧洲各国访问期间结识了贝努利家族,所以对数学研究产生了兴趣:曾担任中学教师.1725年,到了

POJ 2689 - Prime Distance - [筛法求素数]

题目链接:http://poj.org/problem?id=2689 Time Limit: 1000MS Memory Limit: 65536K Description The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number theoreticians for thousan

初等数论-Base-1(筛法求素数,欧拉函数,欧几里得算法)

前言 初等数论在OI中应用的基础部分,同机房的AuSquare和zhou2003君早就写完了,一直划水偷懒的Hk-pls表示很方,这才开始了这篇博客. $P.S.$可能会分部分发表. 筛法求素数 埃式筛素数 问题:求$[1,n]$中的所有素数 总体思路就是在$[2,n]$中每当我们找到一个新的素数,在把它加入我们的素数队列的同时我们把它的倍数全部打上标记(包括它自己),下一个没有被标记的数就是新的素数. void find_prime(int n){ memset(used,0,sizeof(u

线性筛法(欧拉筛法)求素数

时间复杂度O(n)当n比较大时欧拉筛法所用的时间比O(nloglogn)的算法的时间少的会越来越明显 为什么呢? 因为在欧拉筛法中,每一个合数只被访问并将其所对的f[]的值修改了一次. for(i = 2; i <= n; i++) { if(f[i] == 0) { p[++cnt] = i; } for(j = 1; j <= cnt; j++) { if(i * p[j] > n)break; f[i * p[j]] = 1; if(i % p[j] == 0)break; } }

『素数(Prime)判定和线性欧拉筛法(The sieve of Euler)』

素数(Prime)及判定 定义 素数又称质数,一个大于1的自然数,除了1和它自身外,不能整除其他自然数的数叫做质数,否则称为合数. 1既不是素数也不是合数. 判定 如何判定一个数是否是素数呢?显然,我们可以枚举这个数的因数,如果存在除了它本身和1以外的因数,那么这个数就是素数. 在枚举时,有一个很简单的优化:一个合数\(n\)必有一个小于等于\(\sqrt{n}\)的因数. 证明如下: 假设一个合数\(n\)没有小于等于\(\sqrt{n}\)的因数. 由于\(n\)为合数,所以除了\(n\)与

【 数学基础】【素数线性筛法--欧拉筛法模板】【普通筛法的优化】

质数(素数):指大于1的所有自然数中,除了1和自身,不能被其它自然数整除的数 合数:比1大,但不是素数的数称为合数,合数除了被1和自身整除,还能被其它数整除 质因数(素因数或质因子):能整除给定正整数的质数,除1以外,两个没有其它共同质因子的正整数称为互质 1和0既非素数又非合数 素数筛法原理:素数的倍数一定不是素数. 实现步骤:用一个boook数组对maxn内的所有数进行标记,1为合数,0为素数,book初始化为0是假设全部数都为素数,从第一个素数2开始,把2的倍数标记为1,然后继续下一轮 欧