• [学习笔记]Miller-Rabin素数检测


    [学习笔记]Miller-Rabin素数检测

    一.什么是Miller-Rabin

    ​ miller-rabin是一个用来检验一个数是不是素数的算法,速度非常的快,(O(log^2n))(加了快速加法)

    二.费马小定理

    ​ 对于素数p,有

    [a^pequiv a;(mod; p) ]

    ​ 这是费马小定理的基本形式。可以变形成为(a^{p-1}equiv1(mod;p))。对于费马小定理来说,大多数时候满足这个式子的一个自然数是一个质数,当然有满足却不是质数的情况。并且不满足他的一定不是质数,这是Miller-Rain算法的基本原理。也就是说,当我们用多个底数a检验一个自然数,发现都满足费马小定理,我们就大约可以认定他是一个质数。

    ​ 对于这样的一类数p(以561为代表):(forall;ain Z,a^{p-1}equiv1(mod;p)),我们称它为Carmichael数,普通的Miller-Rabin是会将他们误判为素数的。

    三.二次探测定理

    ​ 对于一个奇素数(除2以外的素数)来说,一个方程(x^2equiv1(mod;p))的解为(xequiv1(mod;p))(xequiv p-1(mod;p))

    ​ 证:

    [egin{align} x^2equiv1(mod;p)\ x^2-1equiv0(mod;p)\ (x+1)(x-1)equiv0(mod;p) end{align} ]

    ​ 于是对于一个p-1为偶数的指数来说,我们就先把它用二次探测定理做一遍。令(u=frac{p-1}{2}),对(a^uequiv1(mod;p)),(a^uequiv p-1(mod;p)),进行判定。

    四.后记

    ​ 以上的两种方法结合起来应该就可以进行正确的检验素数,但然也可以先把几个常用的素数:2,3,5...17等先判定一遍以此来减小出错概率(笔者还没有测过)

    ​ 对于比较大的数据,乘法(x^2)可能会出现溢出,于是要打一个快速加来模仿乘法。

    五.代码

    #define m_for(i,a,b) for(int i=(a);i<=(b);++i)
    #define ll long long
    const int times=10;
    ll multi(ll a,ll b,ll m)
    {
        ll ans=0%m;
        while(b)
        {
            if(b&1)ans=(ans+a)%m,b--;
            b >>= 1;
            a=(a+a)%m;
        }
        return ans;
    }
    ll KSM(ll a,ll b,ll m)
    {
        ll ans=1%m;
        while(b)
        {
            if(b&1)ans=multi(ans, a, m),b--;
            b>>=1;
            a=multi(a,a,m);
        }
        return ans;
    }
    inline bool Miller_Rabin(ll p){
    	if(p<=2)return p==2;
    	if(!(p&1))return 0;
    	ll u=p-1;
    	int power=0;
    	while(!(u&1))u>>=1,power++;
    	m_for(i,1,times){
    		ll a=rand()%(p-2)+2,x=KSM(a,u,p),y;
    		for(int i=1;i<=power;++i,x=y){
    			if((y=multi(x,x,p))==1&&x!=1&&x!=p-1)return 0;
    		}
    		if(x!=1)return 0;
    	}
    	return 1;
    }
    
  • 相关阅读:
    composer使用git作为仓储
    monolog记录日志
    lumen laravel response对象返回数据
    lumen中间件 Middleware
    AcWing 901. 滑雪
    leetcode 34. 在排序数组中查找元素的第一个和最后一个位置
    acwing 902. 最短编辑距离
    ACWING 844. 走迷宫
    leetcode 5199. 交换字符串中的元素
    AcWing 836. 合并集合
  • 原文地址:https://www.cnblogs.com/clockwhite/p/12148877.html
Copyright © 2020-2023  润新知