• POJ 1811 Prime Test 素性测试 分解素因子


    题意:

    给你一个数n(n <= 2^54),判断n是不是素数,如果是输出Prime,否则输出n最小的素因子


    解题思路:

    自然数素性测试可以看看Matrix67的  素数与素性测试

    素因子分解利用的是Pollard rho因数分解,可以参考 Pollard rho因数分解

    存个代码~


    /* **********************************************
    Author      : JayYe
    Created Time: 2013-9-25 16:02:25
    File Name   : JayYe.cpp
    *********************************************** */
    
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    #include <algorithm>
    using namespace std;
    #define Time 12 // Miller测试次数
    typedef __int64 ll;
    
    const ll INF = 1LL << 61;
    const int maxC = 240;
    
    ll big_mul(ll a, ll b, ll n) {
        ll ret = 0;
        a %= n;
        while(b) {
            if(b & 1) {
                ret += a;
                if(ret >= n)    ret -= n;
            }
            a *= 2;
            if(a >= n)  a -= n;
            b /= 2;
        }
        return ret;
    }
    
    ll pow_mod(ll x, ll n, ll m) {
        ll ret = 1;
        x %= n;
        while(n) {
            if(n & 1)   ret = big_mul(ret, x, m);
            x = big_mul(x, x, m);
            n /= 2;
        }
        return ret;
    }
    
    // 以a为基对n进行Miller次测试并进行二次探测,返回true则是合数
    bool Wintess(ll a, ll n) {
        ll m = n-1;
        int top = 0;
        // n-1 = m*(2^top)
        while(m % 2 == 0) {
            m /= 2;
            top++;
        }
        ll x = pow_mod(a, m, n), y;
        for(int i = 0;i < top; i++) {
            y = big_mul(x, x, n);
            if(y == 1 && (x != 1 && x != n-1))
                return true;
            x = y;
        }
        if(y > 1)   return true;
        return false;
    }
    
    // 对n进行ts次 Miller素性测试
    bool Miller_Rabin(int ts, ll n) {
        if(n == 2)  return true;
        if(n == 1 || n % 2 == 0)  return false;
        srand(time(NULL));
        for(int i = 0;i < ts; i++) {
            ll a = rand() % (n-1) + 1;
            if(Wintess(a, n))   return false;
        }
        return true;
    }
    
    ll ans;
    
    ll gcd(ll a, ll b) {
        return b ? gcd(b, a%b) : a;
    }
    
    // 对n进行因式分解,找出n的一个因子,该因子不一定是最小的
    ll Pollard(ll n, int c) {
        srand(time(NULL));
        ll i = 1, k = 2, x = rand()%n, y = x;
        while(true) {
            i++;
            x = (big_mul(x, x, n) + c) % n;
            ll d = gcd(y - x, n);
            if(d > 1 && d < n)  return d;
            if(y == x)  return n; // 如果该数已经出现过,直接返回
            if(i == k) {
                y = x; k <<= 1;
            }
        }
    }
    
    // 找出所有素因子
    void solve(ll n, int c) {
        if(n == 1)  return ;
        // 判断是否为素数
        if(Miller_Rabin(Time, n)) {
            if(ans > n) ans = n;
            return ;
        }
        ll m = n;
        while(m == n) {   // 找出n的一个因子
            m = Pollard(n, c--);
        }
        solve(m, c);
        solve(n/m, c);
    }
    
    int main() {
        int t;
        ll n;
        scanf("%d", &t);
        while(t--) {
            scanf("%I64d", &n);
            if(Miller_Rabin(Time, n))
                puts("Prime");
            else {
                ans = INF;
                solve(n, maxC);
                printf("%I64d
    ", ans);
            }
        }
        return 0;
    }
    
     
    


  • 相关阅读:
    Java数据结构与算法(24)
    urllib2使用总结
    Python常见文件操作的函数示例
    Java数据结构与算法(23)
    python代码风格检查工具──pylint
    Python抓取框架:Scrapy的架构
    Java数据结构与算法(22)
    【codeforces 431D】Random Task
    【codeforces 449C】Jzzhu and Apples
    【codeforces 20B】Equation
  • 原文地址:https://www.cnblogs.com/riskyer/p/3339340.html
Copyright © 2020-2023  润新知