1)传统找质数的方法(优化筛选次数)
bool isPrime ( int num) {
for ( int i= 2 ; i<= sqrt ( num) ) {
if ( num% i== 0 )
return false;
}
return true;
}
如果要找从
[
1
,
1
e
6
]
[1,1e6]
[ 1 , 1 e 6 ] 中的所有质数,时间复杂度很高
2)欧拉筛
算法思想:遍历到
2
2
2 的时候,筛掉范围内所有
2
2
2 的倍数(因为除了
1
1
1 和自身以外,一定能被
2
2
2 整除),到
3
3
3 的时候,筛掉所有
3
3
3 的倍数··· 注意:如果计算
[
l
,
r
]
[l,r]
[ l , r ] 之间出现的质数的个数?可以用前缀和的思想;当
n
n
n 过大时,
i
×
i
i×i
i × i 容易出现数组越界的错误,即可能
R
u
n
t
i
m
e
E
r
r
o
r
RuntimeError
R u n t im e E rror ,此时要将线性筛中第二个
f
o
r
for
f or 中的
j
=
i
×
i
j=i×i
j = i × i 改为
j
=
i
+
i
j=i+i
j = i + i
# include <bits/stdc++.h>
using namespace std;
const int N= 1e5 ;
int f[ N] ;
bool vis[ N] ;
int p[ N] ;
int idx, n;
void get_primes ( int n)
{
f[ 1 ] = 0 ;
for ( int i= 2 ; i<= n; i++ )
{
if ( ! vis[ i] ) {
f[ i] = f[ i- 1 ] + 1 ;
p[ ++ idx] = i;
for ( int j= i* i; j<= n; j+= i)
vis[ j] = true;
} else
f[ i] = f[ i- 1 ] ;
}
}
int main ( )
{
cin>> n;
int l, r;
cin>> l>> r;
get_primes ( n) ;
cout<< "1~" << n<< "之间的素数分别是:" ;
for ( int i= 1 ; i<= idx; i++ ) {
cout<< p[ i] ;
if ( i!= idx)
cout<< "," ;
}
cout<< endl;
cout<< l<< "~" << r<< "所出现的素数个数为:" << f[ r] - f[ l- 1 ] << endl;
return 0 ;
}
const int N= 5e4 + 5 ;
int primes[ N] , cnt;
bool st[ N] ;
int ans[ N] , len;
void get_primes ( int n) {
for ( int i= 2 ; i<= n; i++ ) {
if ( ! st[ i] ) primes[ cnt++ ] = i;
for ( int j= 0 ; primes[ j] * i<= n; j++ ) {
st[ primes[ j] * i] = true;
if ( i% primes[ j] == 0 ) break ;
}
}
}
bool is_prime ( int x) {
if ( x< N) return ! st[ x] ;
for ( int i= 0 ; primes[ i] <= x/ primes[ i] ; i++ )
if ( x% primes[ i] == 0 )
return false;
return true;
}