素数判断及相关定理
素数
素数:一个整数大于1除了1和它自己,没有其他约数即为素数
数学语言:\(\forall n \in Z^+ 且 n>=2 同时只存在1|n,n|n\)
与之相反,合数的定义即为除了1和它自己还有约数
小知识:素数只有2和素奇数
素数筛法
穷举法
及枚举\((1,n)\)的所有数,如果某个数能整除则不是素数
优化:枚举区间\((1,\sqrt n]\)
简单说明:一个数的一对因数(我们定义这对因数乘积为n)要么大于\(\sqrt n\)要么小于\(\sqrt n\),所以只用枚举小于\(\sqrt n\)的因数枚举完即可
不存在一对因数同时小于\(\sqrt n\) 如果小于两数乘积势必小于\(n\)
举例
\(n=16\)
\(n\)的因数:\(1,16,2,8,4,4\)
分成每对\((1,16)(2,8)(4,4)\)
只用枚举\((1,4]\)即可
埃氏筛法
埃氏筛法的核心便是找到一个素数后,筛去这个素数的倍数,(用数组标记),因为这个素数的倍数一定不为素数(合数)
但是埃氏筛法会重复筛合数,会影响效率
比如30,发现2是素数时,会筛去30,但又发现5是素数时,又会再筛去一次
欧拉筛法
欧拉筛法便优化了埃氏筛法,使得每个合数只被筛去一次
- 先介绍一个素数定理,任一合数可以表现为若干素数积
简单说明:一个合数一定可以分成除了1和它本身以外的因数,而其他因数可以为素数或者合数,那么合数还是可以分为素数或合数,所以不断的拆分成,直到全为素数
根据这个定理我们可以规定,一个合数可以等于它的最小质因数×某个合数或素数
合数=min(素数)×(合数或素数)
欧拉筛法会用一个数组(isprime[])依次存放素数,此时的素数数组是递增的
那么设x=i*isprime[j]
\(isprime[j]\)一定为素数,i为素数或合数
所以假设\(isprime[j]\)为最小素因数,所以i的因数中不能有小于\(isprime[j]\)的因数(除了1)
所以只需要判断 \(i%isprime[j]==0\) 是否成立即可
当然也可以反证
假设\(i%isprime[j]==0\)
因为\(isprime[]\)是递增的
则合数\(i*isprime[j+1]=isprime[j]*(k*isprime[j+1])(k=i/isprime[j])\)
- \(k>isprime[j]\)简单说明 因为合数被表示为最小质因数*某个合数,此时合数\(i*pirme[j]\)中,\(prime[j]\)为最小质因数,\(i\)为某个合数,根据我们的规定,i中的因数不能有小于\(prime[j]\)的,所以\(i\)的因数\(prime[j]\)和\(k\)都大于或等于\(prime[j]\)
其中\(isprime[j]<isprime[j+1]\) 所以isprime[j]为最小质因数,这个合数被isprime[j](kisprime[j+1])已经筛掉了,大于\(isprime[j]\)同理,所以不同再筛了
[线性筛模板(https://www.luogu.com.cn/problem/P3383)
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxx=100000000+10;
int s[6000000+10];
bool isprime[maxx];
int main(){
int n,q;
std::ios::sync_with_stdio(0);
cin>>n>>q;
int top=1;
memset(isprime,1,sizeof(isprime));
isprime[1]=0;
for(int i=2;i<=n;++i){
if(isprime[i])
s[top++]=i;
for(int j=1;j<=top && i*s[j]<=n;++j){
isprime[i*s[j]]=0;
if(i%s[j]==0) break;
}
}
for(int i=1;i<=q;++i){
int pl;
cin>>pl;
cout<<s[pl]<<endl;
}
return 0;
}
相关定理
惟一分解定理
若整数\(a>=2\),那么a一定可以表示为若干个素数的乘积(惟一的形式)即 \(a=p_1^{a_1}*p_2^{a_2}*p_3^{a_3}*......*p_n^{a_n}(\forall p \in 素数,\forall a_i \in Z^{+})\)
例如\(48=2^4*3\)
威尔逊定理
若p为素数 则\((p-1)!=-1(\mod p)\)
威尔逊定理的逆定理同样成立
即:若某一正整数p,\((p-1)!=-1(\mod p)\)则p一定为素数
证明(见其他博客吧)(我真的证不来)
- 应用
根据威尔逊定理则\(p|((p-1)!+1)\),利用sin函数特点,构造出一个素数函数分布曲线
\(f(n)=sin(Π*((n-1)!+1)/n)\)使函数值为0的点就是素数\((Π为pai)\)
费马小定理
若\(p\)为素数,\(a\)为正整数,且\(gcd(a,p)=1\)则\(a^{p-1}=1(\mod p)\)
-
证明
取\((p-1)\)个整数\(a,2a,3a,.......,(p-1)a\),其中任一整数都不是p的倍数,且皆不同余于模p则构造素数P的完全剩余系
$ P=$ {$ 1,2,.....,p-1$}
即可构造又一个A的完全剩余系
$ A=$ {$ a,2a,.....,(p-1)a$}
(解释,\(gcd(a,p)=1\),\(a*x(\forall x<(p-1))\),又因为P的完全剩余系中两两互不同余于p,则利用同乘性,A的完全剩余系两两互不同余)
由完全剩余系定义
\(a*2a*3a*.....*(p-1)a=1*2*3....*(p-1)(\mod p)\)
化简
\((p-1)!*a^{p-1}=(p-1)!(\mod p)\)
则\(a^{p-1}=1(\mod p)\)
p为整数时\(a^p =a (\mod p)\)