Eratosthenes篩選法與尤拉篩選法
儘管程式碼已經相當高效了,但仍然可以進行改進.首先,在"對於不超過n的每個非負數p"中,p可以限定為素數--只需在第二重迴圈前加一個判斷if(!vis[i])即可.另外,內層迴圈也不必從i * 2開始--它已經在i = 2時被篩選了.改進後代碼如下:void isprime(int n)///篩選1-n的素數 { memset(vis,0,sizeof(vis)); for(int i = 2; i <= n; i++) for(int j = 2 * i; j <= n; j += i) vis[j] = 1; }
void isprime(int n)///篩選1-n的素數 { memset(vis,0,sizeof(vis)); int m = sqrt(n + 0.5); for(int i = 2; i <= m; i++) { if(!vis[i]) { for(int j = i * i; j <= n; j += i) vis[j] = 1; } } }
Eratosthenes篩選法雖然效率高,但是Eratosthenes篩選法做了許多無用功,一個數會被篩到好幾次,最後的時間複雜度是O(nloglogn),對於普通素數演算法而言已經非常高效了,但尤拉篩選法的時間複雜度僅僅為O(n).
尤拉篩選法的思想就是不做無用功,原本Eratosthenes篩法的第一重迴圈是用來找素數,然後把素數的倍數標記,而尤拉篩法換了一個角度,第一位是找素數沒有問題,但是標記的時候用的是所有數.尤拉篩選法在資料小的時候不如Eratosthenes篩選法快,反而是資料變大以後,兩者差距變得越來越明顯,尤拉篩選法明顯快於Eratosthenes篩選法.尤拉篩選法程式碼如下:
const int Max = 100002;
int Prime[Max];
bool vis[Max];
void prepare()
{
int num = 0;
memset(vis,true,sizeof(vis));
for(int i = 2; i <= Max; ++i)
{
if(vis[i])
Prime[++num] = i;
for(int j = 1; j <= num; ++j)
{
if (i * Prime[j] > Max)
break;
vis[i * Prime[j]] = false;
if (i % Prime[j] == 0)
break;
}
}
}
相關推薦
【演算法】3.Eratosthenes篩選法與尤拉篩選法求素數
Eratosthenes篩法 1.原理 一個合數可以分成幾個素數的和,如果把素數(最初只知道2)的倍數全都去掉,剩下的就都是素數了 2.思路分析 去除0,1(既不是素數又不是合數) 找到佇列中最小的素數,刪除其倍數 3.程式碼實現(只給出了函
Eratosthenes篩選法與尤拉篩選法
Eratosthenes篩選法與尤拉篩選法 由於一個合數總是可以分解成若干個質數的乘積,那麼如果把質數的倍數都去掉,那麼剩下的就是質數了.Eratosthenes篩選法的思想特別簡單:對於不超過n的
小於等於n的素數的個數(埃式篩選法和尤拉篩選)
問題描述 給定數字n,求出小於等於n的素數的個數,假設n<=1000000 思路 找出數字n之前的所有素數,用陣列isprime[i]表示i是否是素數;用num[i]表示小於等於數字i的素數有多少。 那麼最重要的就是解決判斷一個數是否是素數 方法
尤拉函式求法與尤拉篩法求素數
尤拉函式: 尤拉函式定義: 對於正整數n,尤拉函式Euler(n)是1到n-1中與n互質的數的個數,特別的,Euler(1) = 1,若n為質數則有 Euler(n) = n - 1 尤拉函式的兩種求法: 1.由定義和常識可以知道對
埃氏篩法和尤拉篩法的區別
Eratosthenes篩法(Sieve of Eratosthenes) 由於思想非常簡單,故只給出實現。 void eratosthenes_sieve(int n) { totPrimes = 0; memset(flag, 0, size
求素數個數(埃氏篩法和尤拉篩法)
求1——n的素數的個數,有以下三種方法: 普通的O()演算法: #include<iostream> #include<cstdio> #include<cmath> using namespace std; bool isprim
線性篩選素數(尤拉篩選)
bool ok[maxn];//自然數表 int prime[maxn];//素數陣列 int tol;//素數長度 void make_prime() { tol = 0; for(int i
Prime Path-POJ3126-1尤拉篩選法+BFS-好題
題意: 給你兩個四位數的質數m,n(m<=n),每次變化只能改變當前數的一個數字,並且過程中的數字全是四位數的質數,求最小的步數。 思路: 先尤拉篩選法求出素數,然後從m開始BFS,每次只改變一個
O(N)的素數篩選法和尤拉函式
首先,在談到素數篩選法時,先涉及幾個小知識點. 1.一個數是否為質數的判定. 質數,只有1和其本身才是其約數,所以我們判定一個數是否為質數,只需要判定2~(N - 1)中是否存在其約數即可,此種方法的時間複雜度為O(N),隨著N的增加,效率依然很慢。這裡有
尤拉定理、拓展尤拉定理及其應用(尤拉降冪法)
摘要 本文主要介紹了數論中的尤拉定理,進而介紹尤拉定理的拓展及應用,結合例題展示如何使用拓展尤拉定理實現降冪取模。 在數論中,尤拉定理,(也稱費馬-尤拉定理)是一個關於同餘的性質定理。瞭解尤拉定理之前先來看一下費馬小定理: a是不能被質數p整除的正整數,則有a^(p
線性尤拉篩法
合數指自然數中除了能被1和本身整除外,還能被其他數(0除外)整除的數 時間複雜度O(n) 每個合數只會被他的最小的質因子篩去。 #include<iostream> #include<cmath> #include<cstring> usi
【模板】尤拉篩法(線性篩法)
1 int n; 2 int p[MAX_N], cnt; 3 bool b[MAX_N]; 4 5 void Euler() 6 { 7 b[0] = b[1] = 1; 8 for(register int i = 2; i <= n; ++i) 9
[模板]線性篩素數(尤拉篩法)
用途 $O(n)$處理出n以內所有素數 原理 使用 合數=最大因數(除1和本身外)*最小質因數 的原理來篩,每個數只會被篩一次 對於每個數i,令它是某數的最大因數,然後從小到大地找<=i的素數j,則i*j是合數 直到找到某個j使得$i\%j==0$,因為再往後的話,j'> i的某個因子,
【演算法模板】尤拉篩法求素數
#include<iostream> using namespace std; const int MAXN=1000000+10; int n,cnt,prime[MAXN]; bool vis[MAXN]; void findprime(int n)
數論 之 篩法總結(艾托拉斯特尼篩法+尤拉篩法)
1.篩法: 2.埃拉託斯特尼篩法(素數/質數篩選法): 2.1 步驟: 給出要篩數值的範圍n,找出以內的素數。先用2去篩,即把2留下,把2的倍數剔除掉;再用下一個素數,也就是3篩
素數個數-尤拉篩法
模擬的時候真沒想到這是一道這麼麻煩的題。。。 先來看題: 素數個數 題目描述 求1,2,\cdots,N1,2,⋯,N 中素數的個數。 輸入輸出格式 輸入格式: 1 個整數N。 輸出格式: 1 個整數,表示素數的個數。
『素數(Prime)判定和線性尤拉篩法(The sieve of Euler)』
<更新提示> <第一次更新> <正文> 素數(Prime)及判定 定義 素數又稱質數,一個大於1的自然數,除了1和它自身外,不能整除其他自然數的數叫做質數,否則稱為合數。 1既不是素數也不是合數。
BZOJ 2818: 尤拉篩法求gcd(x,y)==k(k為質數)
Description 給定整數N,求1<=x,y<=N且Gcd(x,y)為素數的 數對(x,y)有多少對. Input 一個整數N Output 如題 Sample Input 4 Sample Output 4 Hint
尤拉篩選+唯一分解(模板)
#include<bits/stdc++.h> #define MAXN 1000005 using namespace std; typedef long long ll; ll prime[MAXN]; ll vis[MAXN]; ll cnt; ll n;
Farey Sequence——(篩法求尤拉函式)
傳送門 A - Farey Sequence Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d &