zoukankan      html  css  js  c++  java
  • Miller Rabin

    Miller Rabin

    素性检测,用来判断一个数 (num) 是否为质数,但提前说明,这是一个充分不必要条件,也就是说, (num) 为质数,一定能通过素性检测,但通过素性检测的不一定都是质数。

    笔者向来喜欢 define int long long ,所以不用担心本篇文章的数据。

    先给出两个小定理

    我们很显然的知道除了 (2) 是一个质数外,其他的偶数必然是合数,那么我们就能够知道其他的质数必然是奇数(我们对于 (2) 直接特判一下即可) , 我们就可以将该数 (n) 一定可以被表示为 (n = d imes 2^r + 1) ,也就是 (n - 1 = d imes 2^r)

    则以下两个式子任意满足一个就说明其实可以通过素性测试的。

    [egin{cases} a^d equiv 1 (mod n) \ exists 0 leq i < r , a^{d imes 2^{i}} equiv -1 (mod n) end{cases} ]

    根据前人的经验:我们选择 (a) 为100以内的大概 (10) 个质数的时候,在 (long long) 范围内极极极极极小概率会出错。

    满足其中一个就可以说明通过素性检测了,但不代表通过素性检测就是一个素数,哪怕是两个都满足,这两个均为充分不必要条件。
    (Code)

    bool miller_rabin(int n , int a) //检测 $a$ 这个数是否能让 $n$ 通过素性测试 
    {
    	int d = n - 1 , r = 0 ; 
    	while(!(d % 2)) {d /= 2 ; r++ ; } // 取出 $d$ 和 $r$ 
    	int x = quick(a , d , n) ; // a ^ d % n  
    	for(qwq int i = 0 ; i <= r - 1 ; i++) 
    	{
    		if(x == n - 1) return true ; 
    		x = x * x % n ; //这里应用快速乘 
    	} 
    	return false ; 
    } 
    

    另外一种小检测(更好写)

    费马小定理,因为前面的两个小定理都是费马小定理的扩展形式,那同时是不是说明,我们可以直接通过费马小定理乱搞呢?这答案经过验证是可行的。

    过程: 我们随机出来一个 (a) , 然后我们判断一下 (a^{num - 1} equiv 1(mod num )) 是否成立,如果成立我们就认为通过测试了,如果不通过测试,那么就说明 (num) 一定不是质数。然后我们多来几次,我们就大概率认为其 (num) 为质数了。乱搞。!!!

    • (quick) 表示快速幂
    bool query(int num){
        if(num == 2) return true ; 
        for(qwq int i  = 0 ; i  < base ; i++) 
        {
        	int x = rand() % (num - 2) + 2;
        	if(quick(x ,num , num) != x) return false ;
    	}
    	return true ; 
    }
    

    其他的素数判断方法就不必了

  • 相关阅读:
    case when then 根据不同条件 查询不同的数据 相当于 if-else if-else
    完美的拼接sql语句,中间可以加字符等东西,
    C++抽象类
    C #引用NuGet程序包MySQLData问题
    win10磁盘100%占用解决方法
    C# ASP.NetCore 检测到包降级
    VS 命令“npm install”已退出的问题
    序列化和反序列化含义
    数据库MySQL忘记本地密码
    MongoDB授予权限
  • 原文地址:https://www.cnblogs.com/Zmonarch/p/14725670.html
Copyright © 2011-2022 走看看