Book--筛法求素数

废话不多说,就是开一个bool数组(较大),初始都赋为false,然后把非素数用2层循环找出非素数,赋为true。思路很简单。

首先上一个速敲版的:

for(int i = 2; i <= MAXN; i++)

     if( ! arr[i] )

        for(int j = i * 2; j <= MAXN; j += i)

            arr[j] = 1; //表示是合数

for(int i = 2; i * i <= MAXN; i++) if( ! arr[i] ) for(int j = i * i; j <= MAXN; j += i) arr[j] = 1; //表示是合数


下面看看一个比较高效的:

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;

#define MAXN 100000000
bool arr[MAXN+5];
void buildform()
{
    memset(arr,0,sizeof(arr));
    for(int i = 4 ; i <= MAXN ; i += 2)//先考虑2的倍数,为了配合下面的2层循环
    {
        arr[i] = true;
    }
    int k = sqrt(1.0 * MAXN);
    for(int i = 3 ; i <= k ; i += 2)//只考虑奇数
    {
        for(int j = i*i ; j<=MAXN ; j+=i)
        {
            arr[j] = true;
        }
    }
    return;
}

 


从筛法素数表我们可以看到,它核心思想是:多角度看问题、从另一面解决问题往往高效。
最近看到”一个求一个数所有因数和“的问题。
由于输入的数据量巨大,所以一般的解法(即从1到n枚举相加)
肯定超时(设数据量为一百万,求某个数m时间为c*O(m),复杂度O(m),总复杂度很容易破亿数量级)
所以,换个角度,参考快速欧拉函数算法。

void facsum()
{
    memset(arr,0,sizeof(arr));
    for( int i = 1 ; i < MAXN ; i++)
    {
        for( int j = i + i ; j < MAXN ; j += i )//式子很灵活,若因数不包含本身则这么写,若包含则写int j = i;
        {
            arr[ j ] += i;
        }
    }
}

 

posted @ 2014-05-27 21:13  Naturain  阅读(155)  评论(0编辑  收藏  举报