ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Miller-Rabin

2020-11-26 20:33:17  阅读:204  来源: 互联网

标签:return int Miller sum 算法 MUL 质数 Rabin


算法简介

Miller-Rabin 算法可以较快地判断一个数是不是质数。
但是,这个算法是概率性算法,即有一定的概率会误判。
所以,一般会使用较多的数检验,从而降低误判的概率。

前置定理

费马小定理:\(a^{p-1} \equiv 1 (mod\ p)\)
注意:费马小定理的逆命题并不一定成立。
二次探测定理:若 \(p\) 为奇素数且 \(x^2 \equiv 1 (mod\ p)\) , 则 \(x \equiv 1 (mod\ p)\) 或 \(x \equiv p-1 (mod\ p)\)

前置算法

快速乘,快速幂

判断过程

设现在用于判断的质数为 \(p\) , 在判断的数为 \(x\) 。
首先,若 \(x=p\) ,则 \(x\) 为质数;若 \(x\) 是 \(p\) 的倍数,则 \(x\) 为合数。
然后,根据费马小定理,若 \(p^{x-1} \% x \neq 1\) , 则 \(x\) 必然是合数。
因为费马小定理的逆命题并不一定成立,所以,现在还并不能确定 \(x\) 就是质数。
接下来,令 \(k=x-1\) 。
1.令 \(k=\frac{k}{2}\) , 设 \(t=p^k \% x\) 。
2.若 \(t \neq 1\) 且 \(t \neq p-1\) ,又因为 \(p^{2k} \% x=1\) ,根据二次探测定理, \(x\) 为合数。
3.若 \(t=p-1\) 或 \(k\) 是奇数,无法继续判断,所以判断 \(x\) 为质数。否则,返回第一步,继续判断。
将多个质数的判断结果合并在一起,即可得到一个正确率极高的结果。

code

#include<iostream>
#include<cstdio>
#define int long long
using namespace std;
const int P[]={2,3,5,7,11,13,17,19,23,29};
int MUL(int a,int b,int p) //a*b%p
{
	if(!b) return 0;
	if(b==1) return a;
	int sum=MUL(a,b/2,p);
	if(b%2) return ((sum+sum)%p+a)%p;
	return (sum+sum)%p;
}
int POW(int a,int b,int p) //a^b%p
{
	if(!b) return 1;
	if(b==1) return a;
	int sum=POW(a,b/2,p);
	if(b%2) return MUL(MUL(sum,sum,p),a,p);
	return MUL(sum,sum,p);
}
bool check(int x)
{
	if(x==0||x==1) return false;
	if(x==2) return true;
	for(int i=0;i<10&&P[i]<=x;i++)
	{
		if(x==P[i]) return true;
		if(x%P[i]==0) return false;
		if(POW(P[i],x-1,x)!=1) return false;
		int k=x-1,t=0;
		if(k%2) continue;
		k/=2,t=POW(P[i],k,x);
		if(t==x-1||k%2) continue;
		while(1)
		{
			k/=2,t=POW(P[i],k,x);
			if(t!=1&&t!=x-1) return false;
			if(t==x-1||k%2) break;
		}
	}
	return true;
}
int x;
signed main()
{
	scanf("%lld",&x);
	puts(check(x)?"YES":"NO");
	return 0;
}

一些提醒

此算法的时间复杂度为 \(O(k \log^3 n)\) (其中, \(k\) 为用于判断的质数个数),在数据较大时非常优秀。
但是,在数据比较小的时候此算法的效率和 \(O(\sqrt{n})\) 的暴力都差很多。所以,在数据小时要慎用。
同时,在乘法不会爆 \(long\ long\) 时最好把快速乘去掉,可以把复杂度降为 \(O(k \log^2 n)\) 。

标签:return,int,Miller,sum,算法,MUL,质数,Rabin
来源: https://www.cnblogs.com/zhs1/p/14043999.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有