首页 > 编程语言 >Miller-Rabin算法

Miller-Rabin算法

时间:2023-09-30 15:13:27浏览次数:41  
标签:return Miller LL 素数 算法 ans Rabin qul mod

原文链接:https://blog.csdn.net/qq_43227036/article/details/100336234

OK,前面已经讲了很多判断素数的方法,在判断一个数是否为素数时我们可以采用试除法,但如要求1-n的范围那么时间复杂度很高,所以有了线性的筛法求素数。
但如果为了判断一个大数是否为素数却要消耗很大的空间,这显然会爆空间,那么该如何有效的判断呢?
这里引入两个知识

费马小定理
费马小定理就是说如果p是一个质数,而整数a不是p的倍数,则有a^(p-1)≡1(mod p)。也可以写做a^p ≡ p (mod p).

二次探测
如果p是一个素数,那么使得x^2 ≡ 1 (mod p)的 x的解只有两种可能,就是x = 1 或者 x = p-1。
证明如下:
x^2 ≡ 1 (mod p)可以转换为 x^2-1 = 0(mod p),然后就化为了(x-1)(x+1) = 0 (mod p), 因此p是整除(x-1)(x+1)。因此x = 1 或者 x = p-1。

那么就可以根据二次探测来检验是否为素数,方法如下

判断n是否为素数
1.根据费马小定理,可以得出a(n-1)%n==1,那么可以把n-1转换成n-1=m*2t,因为n是奇数,所以n-1一定是合数,所以一定可以写成m*2^t,权值m为奇数,否则可以再除以2.
2.从[1,n-1]选取一个数作为a,利用二次探测判断先让y=(am)2,判断y1?
2.1 如果其间y
1,但是x!=1||x!=n-1,那么不满足二次探测,是合数
3.循环t次,如果最后x都不等于1,那么一定是合数
4.因为是检测,所以一次判断不一定准确,我们可以多次循环20次,将误差降到最低。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
LL qul_mul(LL a, LL b, LL mod) {//乘法运算
	LL ans = 0;
	while (b) {
		if (b & 1) ans = (ans + a) % mod;
		a = (a + a) % mod;
		b >>= 1;
	}
	return ans;
}

LL qul_pow(LL a, LL b, LL mod) {//快速幂结合乘法运算
	LL ans = 1;
	while (b) {
		if (b & 1) ans = qul_mul(ans, a, mod)%mod;
		a = qul_mul(a, a, mod) % mod;
		b >>= 1;
	}
	return ans;
}

bool Miller_Rabin(LL n) {
	if (n < 2||!(n&1)) return false;
	if (n == 2) return true;
	int t=0, m=n-1;
	//求n-1=m*2^t
	while (!(m&1)) {
		t++;
		m >>= 1;
	}

	for (int i = 0; i < 20; i++) {
		LL a = rand() % (n - 1) + 1;//[1,n-1]
		LL x = qul_pow(a, m, n);//快速幂
		//判断每一个x^2%n==1?
		for (int j = 0; j < t; j++) {
			LL y = qul_pow(x, 2, n);
			if (y == 1 && x != 1 && x != n - 1) {//如果y==1,但是x不满足二次探测,则是合数
				return false;
			}
			x = y;
		}

		//如果最后x还不等于1,则一定是合数
		if (x != 1) {
			return false;
		}
	}

	return true;
}

int main() {
	int n;
	cin >> n;
	if (Miller_Rabin(n)) {
		cout << "YES\n";
	}
	else cout << "NO\n";
	return 0;
}

标签:return,Miller,LL,素数,算法,ans,Rabin,qul,mod
From: https://www.cnblogs.com/bu-fan/p/17737820.html

相关文章

  • Go 1.19 排序算法
    插入排序(InsertionSort)插入排序是一种简单直观的排序算法,它的基本思想是将待排序的元素插入到已经排好序的序列中,从而得到一个新的有序序列。插入排序的具体过程如下:从第一个元素开始,认为它已经是有序的序列。取出下一个元素,在已经排序的序列中从后向前扫描。如果已经排序的......
  • 算法题解--蓝桥云课跳跃
    题目蓝桥云课跳跃1.看完题目先写了个二维数组,然后就真的不懂了,最后找了个大概能懂的题解,思路大概是是建立坐标,再用递归求出所有路径,找出其中最大的权值和2.遇到的问题还是没思路,而且写下面使用递归的方法时光出错,不是很熟练3.测试结果:4.收获:学习过的static终于派上了用场,......
  • Lempel-Ziv (LZ) 算法及例程
    Lempel-Ziv(LZ)算法是一系列无损数据压缩算法,包括LZ77、LZ78和LZW等。这些算法通过利用字典来存储已经遇到的字符串,并用相应的索引来代替重复出现的字符串,从而实现压缩效果。下面是一个简单的例程,展示了如何使用LZ77算法来压缩和解压缩文本数据。压缩过程:初始化一个空的字典和输......
  • 压缩算法介绍
    压缩算法是一种将文件或数据进行压缩的技术。它可以减小文件的大小,从而节省存储空间,并提高传输效率。以下是一些常见的压缩算法:无损压缩算法:这类算法通过消除文件中的冗余信息来减小文件的大小,同时保留了文件的完整性,即可还原为原始文件。其中,哈夫曼编码和LZ77算法(如DEFLATE)是非常......
  • 算法总结
    排序Quick_SortvoidQuick_Sort(intq[],intl,intr){if(l>=r)return;inti=l-1,j=r+1,x=q[(l+r)>>1];while(i<j){doi++;while(q[i]<x);doj--;while(q[j]>x);if(i......
  • 80道高频算法题Python版
    80道高频算法题来源于牛客网,这些答案都经过了我验证,可以复制粘贴后提交通过:掌握这80道题,99%的测试岗位算法考试都能通过。建议收藏后反复练习。本文为Python版本答案,对于Java版本答案,请在电子书《算法挑战》目录中查看。1、NC1大数加法:中等#计算两个数之和#@paramsstrin......
  • 进化算法中的遗传算法(Genetic Algorithms)
    进化算法中的遗传算法(GeneticAlgorithms)引言进化算法是一类基于自然进化原理的优化算法,通过模拟生物进化过程中的选择、交叉和变异等操作,来求解复杂问题。遗传算法(GeneticAlgorithms)是进化算法中最为经典和常用的一种方法。本文将介绍遗传算法的基本原理、核心操作和应用领域,以及......
  • 基于TOTP算法的Github两步验证2FA(双因子)机制Python3.10实现
    从今年(2023)三月份开始,Github开始强制用户开启两步验证2FA(双因子)登录验证,毫无疑问,是出于安全层面的考虑,毕竟Github账号一旦被盗,所有代码仓库都会毁于一旦,关于双因子登录的必要性请参见:别让你的服务器(vps)沦为肉鸡(ssh暴力破解),密钥验证、双向因子登录值得拥有。双因子登录说......
  • 字符串排序算法+快速排序
    #include<stdio.h>#include<stdlib.h>#include<memory>#include<vector>#include<string>usingnamespacestd;voidswap(int*a,int*b){inttemp=*a;*a=*b;*b=temp;}voidquicksort(int*arr,intsta......
  • 聊聊基于Alink库的决策树模型算法实现
    示例代码及相关内容来源于《Alink权威指南(Java版)》概述决策树模型再现了人们做决策的过程,该过程由一系列的判断构成,后面的判断基于前面的判断结果,不断缩小范围,最终推出结果。如下,基于决策树模型预测天气,是最常见的示例。天气的整个预测过程,就是不断地判断推测的过程。特征......