zoukankan      html  css  js  c++  java
  • 算法学习笔记1.3.2 素数判定

    任务

    给一个正整数N,判定N是否为素数。

    说明

    Miller-Rabin测试:要测试N是否为素数,首先将N-1分解为2^s*d。在每次测试开始时,先随机选一个介于[1,N-1]的整数a,如果对所有在区间[0,s-1]范围内的r都满足a^d mod N <> 1 且 a ^ (2 ^ r * d) mod N <> -1,则N是合数。否则,N有3/4的几率为素数。为了提高测试的正确性,可以选择不同的a进行多次测试。

    接口

    bool isPrime(int N);
    

    复杂度:O(logN)
    输入:N 待测试的整数
    输出:False表示为合数,True表示有很大概率为素数。

    代码

    #include <iostream>
    using namespace std;
    
    long long pow_mod(long long a, long long i, long long n) {
        if (i == 0) return 1 % n;
        long long temp = pow_mod(a, i>>1, n);
        temp *= temp;
        if (i & 1) temp = temp * a % n;
        return temp;
    }
    
    bool test(int n, int a, int d) {
        if (n == 2 || n == a) return true;
        if ( (n&1) == 0) return false;
        while ( !(d&1) ) d >>= 1;
        int t = pow_mod(a, d, n);
        while ( d != n -1 && t != 1 && t != n-1 ) {
            t = (long long) t * t % n;
            d <<= 1;
        }
        return ( t == n-1 || (d & 1) == 1 );
    }
    
    bool isPrime(int n) {
        if (n < 2) return false;
        int a[] = {2, 3, 5};   // 测试集,更广泛的测试范围需要更大的测试集
        for (int i = 0; i <= 2; i ++)
            if (!test(n, a[i], n-1)) return false;
        return true;
    }
    
    int main() {
        for (int i = 2; i <= 100; i ++) {
            if (isPrime(i)) cout << i << endl;
        }
        return 0;
    }
    
    

    使用范例

    HDU2138

  • 相关阅读:
    [HNOI2002]营业额统计
    HDU 1374
    HDU 3345
    HDU 2089
    Graham扫描法
    Codeforces 1144D Deduction Queries 并查集
    Codeforces 916E Jamie and Tree 线段树
    Codeforces 1167F Scalar Queries 树状数组
    Codeforces 1167E Range Deleting
    Codeforces 749E Inversions After Shuffle 树状数组 + 数学期望
  • 原文地址:https://www.cnblogs.com/zifeiy/p/9526291.html
Copyright © 2011-2022 走看看