- 判斷一個數是不是質數,最基礎的方法:
bool isprime(int n) {
if(n <= 1) return 0;
for(int i = 2; i <= sqrt(n); i ++) {
if(n % i == 0) return 0;
}
return 1;
}
這個方法雖然能判斷是不是質數,但效率很低,如果要判斷的這個數很大,那麼多半是會TLE
,所以我們需要更高效的演算法;
- 埃式篩:
ll is_prime[maxn]; //記錄質數
bool vis[maxn]; //判斷是不是質數
void isprime(ll n)
{
vis[0] = 1;
ll cnt = 0; //記錄質數個數
for(ll i = 2; i <= n; i ++){
if(!vis[i]){
is_prime[++cnt] = i;
for(ll j = 2 * i; j <= n; j += i){
vis[j] = 1; //記錄質數的倍數是不是質數
}
}
}
}
埃式篩就會比普通方法要快得多,但它也有個缺點,就是同一個數會被篩很多次,這導致時間上有所損失,所以有什麼辦法可以只篩一次呢?當然有:
- 尤拉篩(也稱線性篩)
ll is_prime[maxn]; //記錄質數
bool vis[maxn]; //判斷是不是質數
void isprime(ll n)
{
vis[0] = 1;
ll cnt = 0; //記錄質數個數
for(ll i = 2; i <= n; i ++){
if(!vis[i]){
is_prime[++cnt] = i;
if(i <= sqrt(n)){
for(ll j = i * i; j <= n; j += i){
vis[j] = 1; //記錄質數的倍數是不是質數
}
}
}
}
}