【数论】Miller_Rabin

Miller_Rabin素数测试

    Miller_Rabin判断单个素数的方法运用了费马小定理,可以说非常之快了。

    Miller_Rabin曾经被称作“黑科技”,但是根据费马小定理其实完全可以自己写出来大半。

其算法的运行过程如下:

(1)对于奇数M,使得N=(2^r)*M+1

(2)选取随机数使得A<N

(3)对于任意i(i<r),若(A^(2^i)) Mod N=N - 1,则N为素数

(4)或者,若(A^M) Mod N=1,则N通过随机数A的测试

若对素数N进行T次测试,那么失误率为1/4^T,我们可以进一步提高其效率,如省去步骤3

   

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<time.h>
#include<cstdlib>
#include<cmath>
using namespace std;
long long exp(long long a,long long m,long long n){//快速幂
	if(m==0) return 1;
	if(m==1) return (a%n);
	long long w=exp(a,m/2,n);
	w=w*w%n;
	if(m&1) w=w*a%n;
	return w%n;
}
bool Witness(long long a,long long n)
{
    long long m=n-1;//满足原先条件
    int j=0;
    while(!(m&1)){
        j++;
        m>>=1;
    }
    long long x=exp(a,m,n);
    if(x==1||x==n-1) return false;
    while(j--){
        x=x*x%n;
        if(x==n-1) return false;
    }
    return true;
}
bool Miller_Rabin(long long n){
	if(n==2) return true;
	if(n&1==0) return false;
	for(int i=1;i<=10;i++){
		long long a=rand()%(n-2)+2;//一定为a<N
		if(Witness(a,n)) return false;
	}
	return true;
}
bool prime(long long N){
	long long k=sqrt(N);
	for(int i=2;i<=k;i++) if(N%i==0) return false;
	return true;
}
int main(){
    srand(time(NULL));
    for(long long i=3;i<=10000000;i++)
    if(Miller_Rabin(i)!=prime(i)) cout<<i<<endl;
}

  

时间: 2024-10-12 23:57:48

【数论】Miller_Rabin的相关文章

数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test

Prime Test Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 29046   Accepted: 7342 Case Time Limit: 4000MS Description Given a big integer number, you are required to find out whether it's a prime number. Input The first line contains the

[数论][Miller_Rabin] Goldbach

Description: Goldbach's conjecture is one of the oldest and best-known unsolved problems in number theory and all of mathematics. It states: Every even integer greater than 2 can be expressed as the sum of two primes. The actual verification of the G

POJ 1181 大整数是否为素数以及求大整数的质因数-数论-(Miller_rabin+Pollard_rho)

题意:求一个整数是否是素数,如果不是,则输出它最小的质因数. 分析: 判断一个大整数是否为素数用Miller_rabin算法,求一个大整数的所有质因数用Pollard_rho算法.这题就是直接套模板. 另外这里的gcd和pow_mod不能用一般的方式,T了.代码里我注释掉的就是T了的写法. 代码: #include<iostream> #include<cmath> #include<ctime> #include<cstdio> #include<a

数论poj题目

http://blog.sina.com.cn/s/blog_76f6777d0101ir50.html 1.素数,整数分解,欧拉函数 素数是可能数论里最永恒,最经典的问题了.素数的判断,筛法求素数,大素数的判断···还有很多其他问题都会用到素数. *最水最水的:(心情不爽时用来解闷吧) pku1365 Prime Land pku2034 Anti-prime Sequences pku2739 Sum of Consecutive Prime Numbers pku3518 Prime Ga

数论基础模板

以前写的几个数论模板,整整吧,反正数论这么弱貌似只会gcd的样子... 来,先来gcd 1. #include<iostream> #include<cstdio> using namespace std; int gcd(int a,int b) { if(b==0) return a; else return gcd(b,a%b); } int lcm(int x,int y) { return (x*y)/gcd(x,y); } int main() { int a,b; s

数论快速入门(同余、扩展欧几里德、中国剩余定理、大素数测定和整数分解、素数三种筛法、欧拉函数以及各种模板)

数学渣渣愉快的玩了一把数论,来总结一下几种常用的算法入门,不过鶸也是刚刚入门, 所以也只是粗略的记录下原理,贴下模板,以及入门题目(感受下模板怎么用的) (PS:文中蓝色字体都可以点进去查看百度原文) 附赠数论入门训练专题:点我打开专题(题目顺序基本正常,用以配套数论入门) 一.同余定理 简单粗暴的说就是:若 a-b == m 那么 a%m == b%m 这个模运算性质一眼看出...直接上入门水题: Reduced ID Numbers 附AC代码(这个也没啥模板....知道就好) #inclu

hdu 4910 Problem about GCD(数论)

题目连接:hdu 4910 Problem about GCD 题目大意:给定M,判断所有小于M并且和M互质的数的积取模M的值. 解题思路:有个数论的结论,若为偶数,M=M/2. 可以写成M=pk,即只有一种质因子时,答案为M-1,否则为1.特殊情况为4的倍数,不包括4. 首先用1e6以内的素数去试除,如果都不可以为p,那么对大于1e6的情况判断一下是否为素数,是素数也可以(k=1),否则开方计算,因为M最大为1e18,不可能包含3个大于1e6的质因子. #include <cstdio> #

《算法导论》——数论

1 . 欧几里得算法(递归法球两个数的最大公约数) 算法比较简单就直接贴代码了: int gcd(int a , int b){     return b ==0 ? a : gcd(b , a%b); } 在这个算法的基础上可以该进,gcd(a*n , b*n)=n*gcd(a , b);这个定理给我们提供了思路:可不可以在算法中加如判断减少递归的次数呢?当然可以. int gac(int m,int n){  if(m==0 || n==0)   return (m==0) ? n : m;

POJ【数论/组合/博弈论】

 POJ[数论/组合/博弈论]题目列表 POJ[数论/组合/博弈论]题目列表 原来的列表比较水,今天换了一个难一些的列表,重新开始做~ 红色的代表已经AC过,蓝色的代表做了但是还没过.这句话貌似在我空间里的每份列表里都有额. 博弈论 POJ 2234 Matches Game POJ 2975 Nim POJ 2505 A multiplication game POJ 1067 取石子游戏 POJ 2484 A Funny Game POJ 2425 A Chess Game POJ 29