大素数判定

START

判断一个数是不是素数可以直接暴力或者是素数筛。

但是对于一个特别大的数,直接用素数筛也有可能TLE。

这个时候就要想点别的办法:

1.

筛选法+试除法

首先用素数筛筛出[2,sqrt(n)+1]的素数,然后用这些素数来判断能不能整除n,如果可以,那么n一定是合数,如果都不行,那么n是素数。

void olas()//欧拉筛
{
    int i,j;
    num=1;
    memset(u,true,sizeof(u));
    for(int i=2;i<=1000000;i++)
    {
        if(u[i])    su[num++]=i;
        for(int j=1;j<num;j++)
        {
            if(i*su[j]>1000000)    break;
            u[i*su[j]]=false;
            if(i%su[j]==0)    break;
        }
    }
}

这里使用的是欧拉筛。

筛出素数后一个for循环结束。

2.Miller_Rabin方法

和费马小定理有关的方法。

费马小定理:a^(p-1)=1 (mod p)。a,p互质。

如果a,p互质,那么一定有费马小定理成立,但是反之未必!

但是如果有非常多个a,都和我们要判定的p满足费马小定理,那么我们认为这个p很有可能是素数或者伪素数。

我们把可以满足上式的但却不是质数的p称为伪素数。

既然a取足够多就可以侧面反映p大概率是素数,那么我们就枚举足够多有代表性的a来验算。

现在来证明这个方法的有效性:

如果a^2=1(mod n),则必有a=1 (mod n)或a=n-1 (mod n)  .

现在,如果有一个大于2的质数n,令n-1=2^s * d 其中d为奇数。根据费马小定理,如果a不能被n整除,则a^(n-1)%n=1。

由以上性质可以推出a^d =1(mod n),或者a^2 =1 (mod n),a^(2^r *d) =1 (mod n) ,(0<=r<s)其中a为任意自然数。

现在只要找到一个a使得a^d != 1(mod n)或者 a^(2^r * d) != 1 (mod n)就可以说明n不是素数。

Miller_Rabin是一个随机化算法,通过反复验证,得出的结论是,如果任一个数p,通过了以2,7,61为底的Miller_Rabin测试,那么它一定是素数,反之不是素数。

typedef long long ll;
ll qpow(ll a,ll b,ll M)
{
    ll ans=1;
    while(b)
    {
        if(b&1)    ans*=a,ans%=M;
        a*=a;a%=M;b>>=1;
    }
    return ans;
}
bool Miller_Rabin_Test(ll x,ll n)//n是待测质数
{
    ll y=n-1;
    while(!(y&1))    y>>=1;
    x=qpow(x,y,n);
    while(y<n-1&&x!=1&&x!=n-1)
    {
        x=(x*x)%n;
        y<<=(ll)1;
    }
    return x==n-1||y&1==1;
}
bool solve(ll n)
{
    if(n==2||n==7||n==61)    return 1;
    if(n==1||(n&1)==0)    return 0;
    return Miller_Rabin_Test(2,n)&&Miller_Rabin_Test(7,n)&&Miller_Rabin_Test(61,n);
}

END

原文地址:https://www.cnblogs.com/cautx/p/11385849.html

时间: 2024-10-27 06:09:06

大素数判定的相关文章

miller_robin大素数判定

参考了ACdreamer大神的博客http://blog.csdn.net/acdreamers/article/details/7913786 在51nod上看了个10^30范围的素数判定,打表肯定是不行了,应该用miller-robin素数判定加java的BigInteger 首先基于fermat小定理就是gcd(a,p)=1时,a^(p-1)%p=1,所以在生成rand(2,p-1)的随机数后,如果输入的是个素数,那么必有pow(a,p-1)%p=1,这里采用快速幂取模,在一次探查后,若结

HLJOJ1171(大素数判定)

多组测试数据,每组测试数据第一行输入一个正整数n(0< n < 10^9). 每组测试数据,若n为素数,那么输出"YES",否则输出"NO".(引号不输出) 思路:由于n非常的大,打表nlogn也不行,我们换一种思路,我们不打10^9,我们只打出它的开平方10^5就差不多了,找出小于10^5以内的素数,然后我们判定n的时候再用 普通素数判别法判定就行 #include <stdio.h> #include <string.h> #

CSU 1552: Friends 图论匹配+超级大素数判定

1552: Friends Time Limit: 3 Sec  Memory Limit: 256 MBSubmit: 163  Solved: 34[Submit][Status][Web Board] Description On an alien planet, every extraterrestrial is born with a number. If the sum of two numbers is a prime number, then two extraterrestri

HDU 4344 大数分解大素数判定

这里贴个模板吧.反正是不太理解 看原题就可以理解用法!! #include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <cstring> #include <map> using namespace std; #define Times 10 typedef __int64 LL; map<LL,int>m; LL

2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 B. Goldbach-米勒拉宾素数判定(大素数)

若干年之前的一道题,当时能写出来还是超级开心的,虽然是个板子题.一直忘记写博客,备忘一下. 米勒拉判大素数,关于米勒拉宾是个什么东西,传送门了解一下:biubiubiu~ B. Goldbach 题目传送门 自己看题意吧,直接贴代码了. 代码: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<cstdlib> 6 #i

重复造轮子之RSA算法(一) 大素数生成

出于无聊, 打算从头实现一遍RSA算法 第一步, 大素数生成 Java的BigInteger里, 有个现成的方法 public static BigInteger probablePrime(int bitLength, Random rnd) { bitLength是期望生成的素数的二进制位数, rnd是随机数发生器 函数注释表明, 这个方法的返回值为合数的概率为2^-100 生成100个1024位的素数, 耗时13471ms 但是显然我不打算直接使用这个函数, 要做就从最底层做起! 目前的做

大素数判断和素因子分解【miller-rabin和Pollard_rho算法】

集训队有人提到这个算法,就学习一下,如果用到可以直接贴模板,例题:POJ 1811 转自:http://www.cnblogs.com/kuangbin/archive/2012/08/19/2646396.html 传说中的随机算法. 效率极高. 可以对一个2^63的素数进行判断. 可以分解比较大的数的因子. 1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<time

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

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

记一次使用快速幂与Miller-Rabin的大素数生成算法

大家都知道RSA的加密的安全性就是能够找到一个合适的大素数,而现在判断大素数的办法有许多,比如Fermat素性测试或者Miller-Rabin素性测试,而这里我用了Miller-Rabin素性测试的算法,具体的理论我写到下面. 算法的理论基础: Fermat定理:若n是奇素数,a是任意正整数(1≤ a≤ n?1),则 a^(n-1) ≡ 1 mod n. 2.  如果n是一个奇素数,将n?1表示成2^s*r的形式,r是奇数,a与n是互素的任何随机整数,那么a^r ≡ 1 mod n或者对某个j