素数
参考资料
素性测试
试除法
枚举 到 的整数试除,存在因子则为合数。时间复杂度为 。
bool prime(int n)
{
if(n<2)return 0;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)return 0;
}
return 1;
}
Fermat 素性测试
基于费马小定理:若 为素数,则对任意 有 。随机取 个底数检验,全部通过则大概率为素数;但卡迈克尔数会被误判。时间复杂度为 。
ll Pow(ll x,ll y,ll mod)
{
x%=mod;
ll res=1;
while(y)
{
if(y&1)res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
bool prime(int n,int k)
{
if(n<3)return n==2;
while(k--)
{
if(Pow(rand()%(n-2)+2,n-1,n)!=1)return 0;
}
return 1;
}
Miller–Rabin 素性测试
在费马测试上增加二次探测:把 ,检验 反复平方的过程中是否出现非平凡的 的平方根,可滤掉卡迈克尔数,误判概率极低。时间复杂度为 。
ll Pow(ll x,ll y,ll mod)
{
x%=mod;
ll res=1;
while(y)
{
if(y&1)res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
bool prime(int n,int k)
{
if(n<3||n%2==0)return n==2;
if(n%3==0)return n==3;
int u=n-1,t=0;
while(u%2==0){u>>=1;t++;}
while(k--)
{
ll v=Pow(rand()%(n-3)+2,u,n);
if(v==1)continue;
int s;
for(s=0;s<t;s++)
{
if(v==n-1)break;
v=v*v%n;
}
if(s==t)return 0;
}
return 1;
}
常见素数
以内:
常见模数:
梅森素数:
日期素数:
特殊含义: