也稱質數、不可約數,不存在非平凡因子。ios
即對於任意數\(n\)都至少存在兩個因子,一個是\(1\),另外一個是\(n\)自己,咱們就叫它倆爲\(n\)的平凡因子,其餘的,都爲n的不平凡因子。c++
設\(\pi (n)\)爲不超過\(n\)的質數個數
那麼,\(\pi (n) \backsim \frac {n}{\ln n}\)(\(n\)越大,估計的越準確)算法
Code:數組
inline int factorize(int x,int p[]) { int cnt=0; for(int i=2; i*i<=x; ++i) { if(x%i==0) { p[cnt++]=i; x/=i; } } if(x>1) p[cnt++]=x; return cnt; }
質數有無限個,如何證實?網絡
反證法:假設質數是有限的
\(\because假設爲p_1,p_2,\cdots p_n\)
\(\therefore M=p_1*p_2*\cdots p_n+1\)
\(又\therefore M \bmod p_1=1\)
\(M \bmod p_2=1\)
\(\cdots\)
\(M \bmod p_n=1\)
\(\therefore M \bmod 任何質數都是1,M不是任何質數的倍數,M是質數,與假設衝突,因此質數有無限個\)dom
這樣一想,求它是否是就有不少種方法啦~(\(Emma,19260817\)是個質數)
1.一個毒瘤的判斷素數法子(跑的賊快的那種,時間複雜度 \(O(\sqrt{n}/3)\)):優化
首先看一個關於質數分佈的規律:
\(\geq5\)的質數必定和\(6\)的倍數相鄰。
\(證實:令x\geq 1,將\geq 5的天然數表示以下:\)
\(\cdots 6x-1,6x,6x+1,6x+2,6x+3,6x+4,6x+5,6(x+1),6(x+1)+1 \cdots\)
\(能夠看到,不和6的倍數相鄰的數爲6x+2,6x+3,6x+4,因爲2(3x+1),3(2x+1),2(3x+2),因此它們必定不是素數,再除去6x自己,顯然,素數要出現只可能出如今6x的相鄰兩側。\)
這種方法裁剪了不和\(6\)的倍數相鄰的數,雖然都沒有下降時間複雜度的階數,但都必定程度上加快了判斷的速度。spa
inline int prime(int n) { if(n==1) return false; if(n==2 || n==3) return true; if(n%6!=1 && n%6!=5) return false; for(register int i=5; i<=sqrt(n); i+=6) if(n%i==0 || n%(i+2)==0) return false; return true; }
#include<bits/stdc++.h> using namespace std; int main() { int n; cin>>n; for(int i=2; i<=n; i++) { if(n%i==0) { cout<<"flase"; return 0; } else { cout<<"true"; return 0; } } }
/* 遇到素數須要打表時,先估算素數的個數: num = n / lnx; num爲大概數字,越大偏差越小(只是估計,用於估算素數表數組大小) 這個打表法效率貌似很高,網上說幾乎達到了線性時間(不知道是真是假=。=) */ #include<iostream> #include<string.h> #include<stdio.h> #include<stdlib.h> #define maxn 10000000 using namespace std; bool visit[maxn+1000000]; int prime[maxn],n; ///prime的大小大概估計一下再開數組。大概是(x/lnx) void getprime() { memset(visit, false, sizeof(visit)); int num = 0; for (int i = 2; i <= n; ++i) { if ( !visit[i] ) prime[++num] = i; for (int j = 1; j <= num && i * prime[j] <= n ; j++) { visit[ i * prime[j] ] = true; if (i % prime[j] == 0) break; } } for(int i=2;i<=n;i++){ if(visit[i]==false) cout<<i<<' '; } } int main() { freopen("素數打表.txt","w",stdout); scanf("%d",&n); getprime(); return 0; }
#include<bits/stdc++.h> using namespace std; int g_g(int x) { int flag=1; for(int i=2; i<=sqrt(x); ++i) { if(x%i==0) flag=0; } if(flag==1) return 1; else return 0; } int main() { freopen("sushu.out","w",stdout); for(int i=9784010; i<=100000000; ++i) { if(g_g(i)) { cout<<i<<","; } } return 0; }
bool isprime(int n) { if(n<2)return false; if(n==2) return true; for(int i=2; i<=sqrt(n); i++) if(n%i==0) return false; return true; }
#include<bits/stdc++.h> using namespace std; int n,m; int fw; int kk; bool a[100000000]; int main() { cin>>n>>m; memset(a,0,sizeof(a)); fw=sqrt(n+0.5);//防止四捨五入 a[1]=1;//不判斷一,直接賦值 for(int i=2;i<=fw;i++)//從二的倍數開始找 { if(a[i]==0)//優化一,只有在a[i]不是合數下判斷。 { for(int j=i*i;j<=n;j+=i)//j=i*i,是重點,應爲2*i等已經被判斷過了 a[j]=1; } } for(int i=1;i<=m;i++) { cin>>kk; if(a[kk]==0) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <map> #define ll long long using namespace std; const int times = 20; int number = 0; map<ll, int>m; ll Random(ll n) { //生成[ 0 , n ]的隨機數 return ((double)rand()/RAND_MAX*n+0.5); } ll q_mul(ll a, ll b, ll mod) { //快速計算 (a*b) % mod ll ans=0; while(b) { if(b&1) { b--; ans=(ans+a)%mod; } b/=2; a=(a+a)%mod; } return ans; } ll q_pow(ll a,ll b,ll mod) { //快速計算 (a^b) % mod ll ans=1; while(b) { if(b&1) { ans=q_mul(ans,a,mod ); } b/=2; a=q_mul(a,a,mod); } return ans; } bool witness(ll a,ll n) { //miller_rabin算法的精華 //用檢驗算子a來檢驗n是否是素數 ll tem=n-1; int j=0; while(tem%2==0) { tem/=2; j++; } //將n-1拆分爲a^r * s ll x=q_pow(a,tem,n); //獲得a^r mod n if(x==1||x==n-1) return true;//餘數爲1則爲素數 while(j--) { //不然試驗條件2看是否有知足的 j x=q_mul(x,x,n); if(x==n-1)return true; } return false; } bool miller_rabin(ll n) { //檢驗n是不是素數 if(n==2)return true; if(n<2||n%2==0)return false;//若是是2則是素數,若是<2或者是>2的偶[]數則不是素數 for(register int i=1; i<=times; i++) { //作times次隨機檢驗 ll a=Random(n-2)+1;//獲得隨機檢驗算子 a if(!witness(a,n))return false;//用a檢驗n是不是素數 } return true; } int main() { ll x; while(cin>>x) { if(miller_rabin(x)) cout<<"Yes"<<endl; else cout <<"No"<<endl; } return 0; }
AT261 與えられた數より小さい素數の個數について
AT807 素數、コンテスト、素數
AT1476 素數斷定
P3383 【模板】線性篩素數
P3912 素數個數code
綜上所述:我仍是喜歡毒瘤,噗嗤ci