POJ Prime Test

来源:互联网 发布:java将object转为date 编辑:程序博客网 时间:2024/05/20 00:37

模板题,代码留作以后用...


#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;const int maxn = 10000;const int S = 20;LL factor[maxn];int tot;//返回(a * b) % c,a,b,c<2^63LL multi_mod(LL a, LL b, LL c){    a %= c;    b %= c;    LL ret = 0;    while(b)    {        if (b & 1)        {            ret += a;            if (ret >= c) ret -= c;        }        a <<= 1;        if(a >= c) a -= c;        b >>= 1;    }    return ret;}//返回x^n mod c ,非递归版LL pow_mod(LL x, LL n, LL mod){    LL ret = 1;    while(n)    {        if(n & 1) ret = multi_mod(ret, x, mod);        x = multi_mod(x, x, mod);        n >>= 1;    }    return ret;}//以a为基,n-1=x*2^t,检验n是不是合数bool check(LL a, LL n, LL x, LL t){    LL ret = pow_mod(a, x, n), last = ret;    for (int i = 1; i <= t; i++)    {        ret = multi_mod(ret, ret, n);        if (ret == 1 && last != 1 && last != (n-1)) return 1;        last = ret;    }    if (ret != 1) return 1;    return 0;}/*素数测试*/bool Miller_Rabin(LL n){    LL x = n - 1, t = 0;    while ((x & 1) == 0) x >>= 1, t++;    bool flag = 1;    if (t >= 1 && (x & 1) == 1)    {        for(int k = 0; k < S; k++)        {            LL a = rand()%(n-1) + 1;            if (check(a, n, x, t))            {                flag = 1; break;            }            flag = 0;        }    }    if (!flag || n == 2) return 0;    return 1;}LL gcd(LL a,LL b){    if (a == 0) return 1;    if (a < 0) return gcd(-a, b);    while (b)    {        LL t = a % b;        a = b;        b = t;    }    return a;}/*大整数素因子分解*/LL Pollard_rho(LL x, LL c){    LL i = 1, x0 = rand() % x, y = x0, k = 2;    while(1)    {        i++;        x0 = (multi_mod(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;        }    }}//递归进行质因数分解Nvoid findfac(LL n){    if (!Miller_Rabin(n))    {        factor[tot++] = n;        return;    }    LL p = n;    while(p >= n) p = Pollard_rho(p, rand() % (n-1) + 1);    findfac(p);    findfac(n / p);    return ;}int main(){    //freopen("aa.in", "r", stdin);    //freopen("bb.out", "w", stdout);    int T; LL n;    cin >> T;    while(T--)    {        cin >> n;        if (!Miller_Rabin(n))        {            printf("Prime\n");            continue;        }        tot = 0;        findfac(n);   //进行大整数的素因子分解        LL ans = factor[0];        for(int i = 1; i < tot; i++)          if(factor[i] < ans)            ans = factor[i];        cout << ans << endl;    }    return 0;}