其他分享
首页 > 其他分享> > 素数筛

素数筛

作者:互联网

欧拉筛法打表

素数定理:
π(x)~x/ln(x)
不超过x的素数有π(x)个

//埃氏筛法
//筛出不超过MAX的素数
const int MAX=100005;
int visited[MAX];
int prime[MAX], cnt0;//筛出的素数的个数
void make_prime()
{
    memset(visited,0,sizeof(visited));
    for(int i=2;i<=MAX;i++)
        for(int j=2*i;j<=n;j+=i)
        {
            visited[j]=1;
        }
    //2的2,3,4,5...n倍
    //3的2,3,4,5...n倍
}
//时间复杂度O(nlog(n))


//改进后的欧拉筛法
//对于不超过n的每一个非负整数p,p限定为素数,第二重循环前面加上一个if(!visited[i])
//内层循环不必从2*i开始,已经被i==2时候筛去了
const int MAX=100005;
int visited[MAX];
//int prime[MAX], cnt0;//筛出的素数的个数
void make_prime()
{
    int m=sqrt(n+0.5);
    memset(visited,0,sizeof(visited));
    for(int i=2;i<=m;i++)
        if(!visited[i])
        	for(int j=i*i;j<=n;j+=i)
        	{
            	visited[j]=1;
        	}
    //2的2,3,4,5...n倍
    //3的2,3,4,5...n倍
}


//欧拉筛
const int MAX=100005;
bool is_prime[MAX];//筛子
int prime[MAX], cnt0;//筛出的素数的个数
void make_prime()
{
	cnt0 = 0;
	memset(is_prime, 0, sizeof(is_prime));
	for (int i = 2; i <= MAX; i++)//i代表筛去的倍数,以及这个数
	{
		if (!is_prime[i])prime[cnt0++] = i;//这个数没被筛,放进素数堆
		for (int j = 0; j < cnt0; j++)//遍历整个素数表,筛去i倍数的所有数字
		{
			if (i * prime[j] > MAX)break;
			is_prime[i * prime[j]] = 1;
			if (i % prime[j] == 0)break;//如果i是prime[j]的倍数,则不需要再筛
		}
        //筛去2的倍数
        //筛去3的倍数
        //筛去4的倍数
	}
    /*
	for (int i = 0; i <= 100; i++)
	{
		printf("%d\n", prime[i]);
	 } 
	 */
}

标签:prime,int,MAX,筛去,素数,visited
来源: https://blog.csdn.net/shen253135371/article/details/96170120