素數基本(埃氏篩法/線性篩法)

一、檢查n是否為素數

??

最簡單思路:所有可能的因數全部試一遍。

?

int gg(int n)
{for(int i=2;i<n;i++){if((n%i)==0)return 0;//有因數就不是素數咯}return 1;
}

?

進一步思考:沒必要枚舉所有的數,每一個小于n^(1/2)的因數i,一定有一個大于n^(1/2)的因數j與之對應,也就是i*j=n,所以枚舉小于等于n^(1/2)的因數即可

?

int gg(int n)
{for(int i=2;i*i<=n;i++){if((n%i)==0)return 0;}return 1;
}

?

二、約數枚舉

?上面已經說過,不需要枚舉所有因數,枚舉出某小因數以后算出對應的大因數即可。

vector<int> gg(int n)
{vector<int> a;for(int i=2;i*i<=n;i++){if((n%i)==0){a.push_back(i);if((n/i)!=i)a.push_back(n/i);//根號n的情況不要重復添加}}return a;
}

?

三、埃氏篩法

?只對一個整數操作,O(N),已經足夠了,如果對許多整數進行素性檢測,還有更高效的算法,比如埃氏篩法。

問題:枚舉n以內所有素數

操作:先把所有整數列出來,然后把2的倍數全部剔除,然后是三的,以此類推,遍歷所有素數,把倍數全部劃去。

對于每個數字i,如果沒被劃去,他一定是素數,因為他不是任何2到i-1數字的倍數。然后就開始劃它的倍數就好。

int a[maxx];
int b[maxx+1];
int gg(int n)
{int p=0;//記錄素數個數for(int i=0;i<n+1;i++)b[i]=1;b[0]=0;b[1]=0;//準備完畢for(int i=2;i<=n;i++){if(b[i]){a[p++]=i;//記錄素數和個數for(int j=2*i;j<=n;j+=i)b[j]=0;//剔除倍數}}return p;//返回素數個數
}

四、區間篩法

?給定整數a和b,請問區間[a,b)內有多少個素數??

思路:之前說過,因為b以內合數的最小質因數一定不超過sqrt(b),如果有sqrt(b)以內的素數表的話,就可以把篩選法用在[a,b)上了,先分別做好[2,sqrt(b))的表和[a,b)的表,然后從[2,sqrt(b))的表中篩得素數的同時,也將其倍數從[a,b)的表中劃去,最后剩下的就是區間[a,b)內的素數了。

//不gg了,這次就來個標準一點的吧
typedef long long ll;
bool is_prime[maxn];
bool is_prime_small[maxn];
void segment_sieve(ll a,ll b) 
{for(ll i=0;i*i<b;++i) is_prime_small[i]=true; //初始化for(ll i=0;i<b-a;++i) is_prime[i]=true; //初始化,注意下標變化,為了省空間for(ll i=2;i*i<b;++i) {if(is_prime_small[i]) {for(ll j=2*i;j*j<b;j+=i) is_prime_small[j]=false;  //篩選[2,sqrt(b));//(a+i-1)/i得到最接近a的i的倍數,最低是i的2倍,然后篩選for(ll j=max(2LL,(a+i-1)/i)*i;j<b;j+=i) is_prime[j-a]=false;}}
}

五、線性實現

篩法很多數被處理了不止1遍,比如6,在素數為2的時候處理1次,為3時候又處理一次,因此又造成了不必要處理。O(nloglogn)已經基本可以滿足一般需要了。

本代碼保證每個合數只會被它的最小質因數篩去,因此每個數只會被標記一次,所以時間復雜度是O(n)

證明略

話不多說,上板子

#include<cstdio>
#include<cstring>
#define MAXN 100005
#define MAXL 1299710
int prime[MAXN];
int check[MAXL];
int tot = 0;
memset(check, 0, sizeof(check));
for (int i = 2; i < MAXL; ++i)
{if(!check[i])prime[tot++] = i;for (int j = 0; j < tot; ++j)//****************************************{if (i * prime[j] > MAXL)break;//*******************check[i*prime[j]] = 1;if (i % prime[j] == 0)break;//******}
}

素數基本就這些內容咯。。。。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/445652.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445652.shtml
英文地址,請注明出處:http://en.pswp.cn/news/445652.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

歐幾里得gcd/extend_gcd

正式敘述前還寫了一點自己的小感受。 問題&#xff1a;求兩個正整數a&#xff0c;b的最大公約數。 大神看來是很簡單的問題&#xff0c;但是對于去年夏天剛學python的我來說&#xff0c;這是個很難的問題&#xff0c;還記得當時一晚上睡不著都在想怎么快一點的求出最大公約數…

python基礎技巧總結(一)

最近總結一下python基礎知識&#xff0c;就暫時棄坑了。 本文總結只屬于python的一些騷操作。。。 后面文章自行去博客學習交流 原地交換 Python 提供了一個直觀的在一行代碼中賦值與交換&#xff08;變量值&#xff09;的方法 x, y 10, 20 print(x, y)x, y y, x print(x…

python基礎技巧總結(二)

一總結的鏈接&#xff1a; 好&#xff0c;我們繼續 一次性初始化多個變量 可以直接賦值&#xff1a; a,b,c,d1,2,3,4 可以利用列表&#xff1a; List [1,2,3] x,y,zList print(x, y, z) #-> 1 2 3 &#xff08;元素個數應與列表長度相同&#xff09; 打印模塊路徑 im…

python基礎技巧總結(三)

前兩篇文章&#xff1a; https://blog.csdn.net/hebtu666/article/details/81698235 https://blog.csdn.net/hebtu666/article/details/81698329 我們繼續總結&#xff1a; 開啟文件分享 Python 允許運行一個 HTTP 服務器來從根路徑共享文件&#xff0c;下面是開啟服務器的…

python基礎技巧總結(四)

前三期請到我博客里找 https://blog.csdn.net/hebtu666 我們繼續總結 except的用法和作用 try/except: 捕捉由PYTHON自身或寫程序過程中引發的異常并恢復 except: 捕捉所有其他異常 except name: 只捕捉特定的異常 except name, value: 捕捉異常及格外的數據(實例) exce…

python基礎技巧總結(五)

前四期到博客找&#xff1a;https://blog.csdn.net/hebtu666 我們繼續說一些好用的函數 split Python split() 通過指定分隔符對字符串進行切片&#xff0c;如果參數 num 有指定值&#xff0c;則僅分隔 num 個子字符串。 語法&#xff1a; str.split(str"", num…

堆的簡單實現

關于堆不做過多介紹 堆就是兒子的值一定不小于父親的值并且樹的節點都是按照從上到下&#xff0c;從左到右緊湊排列的樹。 &#xff08;本文為二叉堆&#xff09; 具體實現并不需要指針二叉樹&#xff0c;用數組儲存并且利用公式找到父子即可。 父&#xff1a;(i-1)/2 子:…

二叉搜索樹實現

本文給出二叉搜索樹介紹和實現 首先說它的性質&#xff1a;所有的節點都滿足&#xff0c;左子樹上所有的節點都比自己小&#xff0c;右邊的都比自己大。 那這個結構有什么有用呢&#xff1f; 首先可以快速二分查找。還可以中序遍歷得到升序序列&#xff0c;等等。。。 基本操…

python基礎小白題

題目1&#xff1a;有1、2、3、4四個數&#xff0c;能組成多少個互不相同且無重復的三位數&#xff1f;都是多少&#xff1f; list_num[1,2,3,4] all_num[] for i in list_num: for j in list_num: for k in list_num : if (i!j) and (i!k) and (j!k): numi*100j*10k all_num…

python基礎小白題2

題目11&#xff1a;判斷101-200之間有多少個素數&#xff0c;并輸出所有素數。 num[] for i in range(100,201): ji//2 for k in range(2,j): if i%k0: break else: num.append(i) print(一共有%d個素數\n這些素數是&#xff1a; %len(num),num ) 輸出結果&am…

python基礎小白題3

題目021&#xff1a;猴子吃桃問題 猴子第一天摘下若干個桃子&#xff0c;當即吃了一半&#xff0c;還不癮&#xff0c;又多吃了一個 第二天早上又將剩下的桃子吃掉一半&#xff0c;又多吃了一個。 以后每天早上都吃了前一天剩下的一半零一個。 到第10天早上想再吃時&#x…

python基礎小白題4

題目031&#xff1a;請輸入星期幾的第一個字母來判斷一下是星期幾&#xff0c;如果第一個字母一樣&#xff0c;則繼續判斷第二個字母。 def tm031(): 【個人備注】&#xff1a;按照題意要求實現了就行 week [monday,tuesday,wednesday,thursday,friday,saturday,sunday] inp…

python基礎小白題5

題目045&#xff1a;統計 1 到 100 之和。 def tm045(): 【個人備注】&#xff1a;簡單&#xff0c;但官網有人寫的更簡單 s 0 for i in range(1,101): si print(s) # 更簡潔的方法 print(sum(range(1,101))) 題目046&#xff1a;求輸入數字的平方&#xff0c;如果平方運算…

快排-荷蘭國旗

在使用partition-exchange排序算法時&#xff0c;如快速排序算法&#xff0c;我們會遇到一些問題&#xff0c;比如重復元素太多&#xff0c;降低了效率&#xff0c;在每次遞歸中&#xff0c;左邊部分是空的(沒有元素比關鍵元素小)&#xff0c;而右邊部分只能一個一個遞減移動。…

快排-前m大元素

描述 給定一個數組包含n個元素&#xff0c;統計前m大的數并且把這m個數從大到小輸 出。 輸入 第一行包含一個整數n&#xff0c;表示數組的大小。n < 100000。 第二行包含n個整數&#xff0c;表示數組的元素&#xff0c;整數之間以一個空格分開 。每個整數的絕對值不超過…

歸并-求逆序數

考慮1,2,…,n (n < 100000)的排列i1&#xff0c;i2&#xff0c;…&#xff0c;in&#xff0c;如果其中存在j,k&#xff0c;滿足 j < k 且 ij > ik&#xff0c; 那么就稱(ij,ik)是這個排列的一個逆序。 一個排列含有逆序的個數稱為這個排列的逆序數。例如排列 26345…

動態規劃概述

注&#xff1a;第一次看不需要全理解&#xff0c;以后動態規劃做多了&#xff0c;再回來看看&#xff0c;會有更深的理解 先符上其它文章&#xff0c;看完這篇就可以開始看這些咯。 萌新&#xff1a; …

動態規劃-背包是否裝滿

很簡單但是需要特別注意的&#xff0c;一定不要錯。 背包&#xff1a; 有n 種不同的物品&#xff0c;每個物品有兩個屬性&#xff0c;v體積&#xff0c;c價值&#xff0c;現在給一個體積為 m 的背包&#xff0c;問最多可帶走多少價值的物品。 狀態轉移方程 dp[i][j]max…

dp打開思路3:HDU1069 POJ3616 POJ1088

HDU 1069 題目鏈接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1069 題意&#xff1a;把給定的長方體&#xff08;不限&#xff09;疊加在一起&#xff0c;疊加的條件是&#xff0c;上面一個長方體的長和寬都比下面長方體的長 和寬短&#xff1b;求這些長方體能…

輸入輸出外掛

板子不解釋 //適用于正負整數 template <class T> inline bool scan_d(T &ret) {char c; int sgn;if(cgetchar(),cEOF) return 0; //EOFwhile(c!?&&(c<0||c>9)) cgetchar();sgn(c?)??1:1;ret(c?)?0:(c?0);while(cgetchar(),c>0&&c&…