素数筛
作者:互联网
欧拉筛法打表
素数定理:
π(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