zoukankan      html  css  js  c++  java
  • Miller Rabin算法学习笔记

    (Miller Rabin)算法学习笔记

    (Miller Rabin)是一种快速的随机化的素数测定方法。

    它基于以下定理

    二次探测定理:若(x^2equiv1pmod p),则(xequiv±1pmod p)

    证明大概就是((x-1)(x+1)equiv0pmod p)

    然后我们选取一个底(a),设你当前要判断的数为(x)

    初始我们判断(a^{x-1})是否为(1),不是判定(x)为合数

    然后判断(a^{frac {x-1}2})是否为(1)(p-1),不是判定(x)为合数

    如此反复,直到指数是奇数或余数为(p-1)为止。

    于是此时我们就认为(x)通过了基于(a)为底的测试。

    一次测试错误率大概是(frac 14)

    多次测试的错误率一般认为是(frac 1{4^x})的,可以接受。

    代码就直接模拟就可以了。

    (upd:)我们可以优化一下,从后往前检测,如果其中有一个通过了二次探测,就判定(x)是质数。

    优化后代码:

    /*bool Test(ll a,ll x)
    {
    	if(a>=x)return 1;
    	ll ret=qpow(a,x-1,x),s=x^1;
    	while(ret==1&&!(s&1))s>>=1,ret=qpow(a,s,x);
    	return ret==1||ret==(x^1);
    }*/
    bool Test(ll a,ll x)
    {
    	if(a>=x)return 1;
    	ll ret,s=x^1;
    	int p=__builtin_ctzll(s);
    	ret=qpow(a,s>>p,x);
    	if(ret==1||ret==(x^1))return 1;
    	while(p--&&ret!=(x^1))ret=mul(ret,ret,x);
    	return p>=0;
    }
    int lst[]={2,3,5,7,11,13,17,19,23};
    bool Miller_Rabin(ll x)
    {
    	if(x==1)return 0;
    	if(x==2)return 1;
    	if(x&1)
    	{
    		for(int i=0;i<9;++i)if(!Test(lst[i],x))return 0;
    		return 1;
    	}
    	return 0;
    }
    

    (2st upd:)在一般是选(2,3,7,61,24251)为基底,此时在(1e16)内只有(46856248255981)是强伪素数。

  • 相关阅读:
    文件光标移动
    python的版本的差别 "2","3"
    java通过jdbc操作Excel
    qt通过odbc操作Excel
    qt读取oracle表数据
    virtual box安装oracle_rac_10g
    oracle rac +standby
    rac不完全恢复
    rac完全恢复学习
    oracle rac搭建(三)--安装中的问题
  • 原文地址:https://www.cnblogs.com/LLCSBlog/p/11755944.html
Copyright © 2011-2022 走看看