一.素性检测(MIller-Rabin)
1.一些基础知识点
(1)位运算
n&1
这里 n&1 就是——判断n是否为奇数
因为n为奇数时,对应的二进制数最低位一定为1,n&1的结果就是1
n为偶数时,相应的最低位为0,n&1的结果就是0.
1&n
这里的 1&n 就是:
检查二进制n的最低位,若为1,则1&n的结果就是1,
若不为1,则1&n的结果就是0.按位与运算符(&)
参加运算的两个数据,按二进制位进行“与”运算。运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;
即:两位同时为“1”,结果才为“1”,否则为0
例如:3&5 即 0000 0011& 0000 0101 = 00000001 因此,3&5的值得1。
(2)快速乘法
由于计算机底层设计的原因,做加法往往比乘法快的多,因此将乘法转换为加法计算将会大大提高(大数,比较小的数也没必要)乘法运算的速度,除此之外,当我们计算a*b%mod的时候,往往较大的数计算a*b会超出long long int的范围,这个时候使用快速乘法方法也能解决上述问题.
快速乘法的原理就是利用乘法分配率来将a*b转化为多个式子相加的形式求解(注意这时使用乘法分配率的时候后面的一个乘数转化为二进制的形式计算).举个栗子
20*14 = 20*(1110)2 = 20*(2^3)*1 + 20*(22)*1+20*(21)*1+20*(2^0)*0 = 160+80+40=280.
上面即为快速乘法的基本原理
2.算法原理
(1)费马定理与二次探测定理
下图片来自与博客:https://blog.csdn.net/ECNU_LZJ/article/details/72675595
马定理只是n是素数的必要条件。即费马定理不成立,n一定是合数;费马定理成立,n可能是素数。
(2)Miller-Rabin测试
3.算法
(1)伪码表示
(2)c++算法
#pragma once
typedef long long ll;
ll Quick_Multiply_Mod(ll a, ll b, ll m)//快速积 ,a与b相乘,模数为m
{
ll ans = 0, temp = a;
while (b)
{
if (b & 1)//判断b为奇数还是偶数,实质是判断b二进制的最后一位是1(奇)还是0(偶数)
{
ans = (ans + temp) % m;
}
temp = (temp + temp) % m;
b >>= 1;//b向右移动一位,相当于b/2
}
return ans;
}
ll Quick_Power_Mod(ll a, ll b, ll m)//快速幂,a为底数,b为指数,m为模数
{
ll ans = 1, temp = a;
while (b)
{
if (b&1)
{
//ans = (ans * temp) % m;
ans = Quick_Multiply_Mod(ans, temp, m);
}
//temp = (temp * temp) % m;
temp = Quick_Multiply_Mod(temp, temp, m);
b >>= 1;
}
return ans;
}
bool Miller_Rabin(ll n)//Miller-Rabing算法
{
if (n == 2)//2是素数
return true;
if (n < 2 || n % 2 == 0)//0,1和偶数不是素数
return false;
//把n-1写成2的k次方*t的形式
int k=0, t=n-1;
while (!(t&1))//如果t不是奇数,就执行。相当于t%2
{
k++;
t >>= 1;//t向右移动一位,相当于t/2
}
//进行20轮测试,增加可靠性
for (int i = 0; i <=20; i++)
{
ll a = rand() % (n - 1) + 1;//选取底数a,1<=a<=n-1
ll b = Quick_Power_Mod(a, t, n);
ll y;
for (int i = 0; i < k; i++)
{
y = Quick_Multiply_Mod(b, b, n);
if (y == 1 && b != 1 && b != n - 1)
return false;
b = y;
}
if (y != 1)
return false;
}
return true;
}
4.参考链接
(1)快速幂与快速乘法原理与代码实现
【基本算法】快速幂和快速乘法详解_Nefu_qky的博客-CSDN博客_快速幂乘法
( 快速乘法/幂 算法详解_StanleyClinton的博客-CSDN博客_快速乘(比较详细,有图解)
(2)Miller-Rabin算法
Miller-Rabin素性测试算法详解_Nicetomeetu-的博客-CSDN博客_millerrabin素数测试算法
Miller-Rabin素数测试算法_forever_dreams的博客-CSDN博客_miller rabin素数测试