• POJ 1811 Prime Test


    题意:对于一个大整数,判断是否质数,如果不是质数输出最小质因子。

    解法:判断质数使用Miller-Rabin测试,分解质因子使用Pollard-Rho,Miller-Rabin测试用的红书模板,将测试集根据matrix67的博客进行了拓展,不过也可以随机取的样子,Pollard-Rho用的kuangbin的模板。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<math.h>
    #include<limits.h>
    #include<time.h>
    #include<stdlib.h>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define LL long long
    using namespace std;
    LL ans = LLONG_MAX;
    LL MUL(LL x, LL n, LL p)//乘法取模
    {
        LL ret = 0;
        LL base = x;
        while(n)
        {
            if(n & 1)
                ret = (ret + base) % p;
            base = (base + base) % p;
            n >>= 1;
        }
        return ret;
    }
    LL POW(LL x, LL n, LL p)//快速幂取模
    {
        LL base = x;
        LL ret = 1;
        while(n)
        {
            if(n & 1)
                ret = MUL(ret, base, p) % p;
            base = MUL(base, base, p) % p;
            n >>= 1;
        }
        return ret;
    }
    bool test(LL n, LL a, LL d)
    {
        if(n == 2) return true;
        if(n == a) return true;
        if((n & 1) == 0) return false;
        while(!(d & 1)) d = d >> 1;
        LL t = POW(a, d, n);
        while((d != n - 1) && (t != 1) && (t != n - 1))
        {
            t = t * t % n;
            d <<= 1;
        }
        return (t == n - 1 || (d & 1) == 1);
    }
    bool isPrime(LL n)//Miller-Rabin测试
    {
        if(n < 2) return false;
        LL a[] = {2, 3, 5, 7, 11, 13, 17, 61, 24251};//测试集,据说1e16内的整数都可以
        for(int i = 0; i < 9; i++) if(!test(n, a[i], n - 1)) return false;
        return true;
    }
    LL gcd(LL a, LL b)//一开始用的__gcd,后来发现好像有负数参数的样子……只好老老实实手写
    {
        if(a == 0) return 1LL;
        if(a < 0) return gcd(-a, b);
        while(b)
        {
            LL t = a % b;
            a = b;
            b = t;
        }
        return a;
    }
    LL pollardRho(LL x, LL c)
    {
        LL i = 1, k = 2;
        LL x0 = rand() % x;
        LL y = x0;
        while(1)
        {
            //cout << i << endl;
            i++;
            x0 = (MUL(x0, x0, x) + c) % x;
            LL d = gcd(y - x0, x);
            if(d != 1 && d != x) return d;
            if(y == x0) return x;
            if(i == k) {y = x0; k += k;}
        }
    }
    void findFac(LL n)
    {
        if(isPrime(n))
        {
            //cout << n << endl;
            ans = min(ans, n);
            return ;
        }
        LL p = n;
        while(p >= n) p = pollardRho(p, rand() % (n - 1) + 1);
        findFac(p);
        findFac(n / p);
    }
    int main()
    {
        int T;
        while(~scanf("%d", &T))
        {
            while(T--)
            {
                ans = LLONG_MAX;
                LL n;
                scanf("%lld", &n);
                if(isPrime(n))
                {
                    puts("Prime");
                    continue;
                }
                findFac(n);
                printf("%lld
    ", ans);
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    SQL语句中的左连接、右连接、内连接的理解心得
    MySQL+Java使用心得(1)
    【转】国内常见WEB安全扫描产品概述
    [C puzzle book] operators
    【Python】Symbol Review
    A function for new storage space of string
    【SRX】折腾了半天终于我的那对SRX210 升级到了 12.1R1.9
    [C puzzle book] Control Flow
    [C puzzle book] types
    荷兰TAC的需求
  • 原文地址:https://www.cnblogs.com/Apro/p/4857046.html
Copyright © 2020-2023  润新知