- zhuzixin 的博客
判定素数
- @ 2025-8-6 8:13:56
⚠️TIPS:所有的代码均为思想,仅供参考使用
最大公约数:
int gcd(int a, int b)
{
return (a % b == 0) ? b : gcd(b, a % b);
}
极简版:
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
最小公倍数:
int lcm(int a, int b)
{
return a / gcd(b, a % b) * b;
}
朴素写法:
bool isprime(int x)
{
if(x < 2) return 0;
for(int i = 2; i <= x / i; i++)
if(x % i == 0)
return 0;
return 1;
}
埃氏筛(memset)
无p数组的版本
int n, cnt = 0;
bool a[100000005];
void sf(int x)
{
memset(a, 1, sizeof a);
a[0] = a[1] = 0;
for(int i = 2; i <= x; i++)
{
if(a[i] == 1)
{
cnt++;
for(int j = i + i; j <= x; j += i)
{
a[j] = 0;
}
}
}
}
有p数组的版本
const int N = 10000005;
int n, p[N], cnt = 0;
bool a[N];
void sf(int x)
{
memset(a, 1, sizeof a);
a[0] = a[1] = 0;
for(int i = 2; i <= n; i++)
{
if(a[i])
{
p[++cnt] = i;
for(int j = i + i; j <= n; j += i)
a[j] = 0;
}
}
}
欧拉线性筛
const int N = 10000005;
int n, p[N], cnt = 0;
bool a[N];
void sf(int n){
memset(a, 1, sizeof a);
a[0] = a[1] = 0;
for(int i = 2; i <= n; i++) {
if(a[i]) p[++cnt] = i;
for(int j = 1; j <= cnt && p[j] * i <= n; j++){
a[p[j] * i] = 0;
if(i % p[j] == 0) break;
}
}
}
举个例子(思想): 1-8
0 1 2 3 4 5 6 7 8
1 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8
0 0 1 1 1 1 1 1 1
i
0 1 2 3 4 5 6 7 8
0 0 1 1 1 1 1 1 1
p[] ->
2
2
0 1 2 3 4 5 6 7 8
0 0 1 1 0 1 1 1 1
以此类推
代码对应(核心)
for(int j = 1; j <= cnt && p[j] * i <= n; j++)
{
a[p[j] * i] = 0;
if(i % p[j] == 0) break;
}