• HDU 3864 D_num Miller Rabin 质数推断+Pollard Rho大整数分解


    链接:http://acm.hdu.edu.cn/showproblem.php?

    pid=3864

    题意:给出一个数N(1<=N<10^18)。假设N仅仅有四个约数。就输出除1外的三个约数。

    思路:大数的质因数分解仅仅能用随机算法Miller Rabin和Pollard_rho。在測试多的情况下正确率是由保证的。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <map>
    #include <cstdlib>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <ctype.h>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <ctime>
    #define PI acos(-1.0)
    #define INF 0x7fffffff
    #define eps 1e-8
    #define maxn 50005
    typedef __int64 LL;
    typedef unsigned long long ULL;
    using namespace std;
    LL Factor[100];
    int t=0;
    LL mul_mod(LL a,LL b,LL n)
    {
        a=a%n;
        b=b%n;
        LL s=0;
        while(b)
        {
            if(b&1)
                s=(s+a)%n;
            a=(a<<1)%n;
            b=b>>1;
        }
        return s;
    }
    LL pow_mod(LL a,LL b,LL n)//求a^b%n
    {
        a=a%n;
        LL s=1;
        while(b)
        {
            if(b&1)
                s=mul_mod(s,a,n);
            a=mul_mod(a,a,n);
            b=b>>1;
        }
        return s;
    }
    bool isPrime(LL n, LL times)
    {
        if(n==2)return 1;
        if(n<2||!(n&1))return 0;
        LL a, u=n-1, x, y;
        int t=0;
        while(u%2==0)
        {
            t++;
            u/=2;
        }
        srand(100);
        for(int i=0; i<times; i++)
        {
            a = rand() % (n-1) + 1;
            x = pow_mod(a, u, n);
            for(int j=0; j<t; j++)
            {
                y = mul_mod(x, x, n);
                if ( y == 1 && x != 1 && x != n-1 )
                    return false; //must not
                x = y;
            }
            if( y!=1) return false;
        }
        return true;
    }
    LL gcd(LL a,LL b)
    {
        if(a==0) return 1;
        if(a<0) return gcd(-a,b);
        return b==0?a:gcd(b,a%b);
    }
    LL Pollard_rho(LL n,LL c)//Pollard_rho算法。找出n的因子
    {
        LL i=1,j,k=2,x,y,d,p;
        x=rand()%n;
        y=x;
        while(true)
        {
            i++;
            x=(mul_mod(x,x,n)+c)%n;
            if(y==x)return n;
            if(y>x)p=y-x;
            else p=x-y;
            d=gcd(p,n);
            if(d!=1&&d!=n)return d;
            if(i==k)
            {
                y=x;
                k+=k;
            }
        }
    }
    void factor(LL n)
    {
        if(isPrime(n,20))
        {
            Factor[t++]=n;
            return;
        }
        LL p=n;
        while(p>=n)p=Pollard_rho(p,rand()%(n-1)+1);
        factor(p);
        factor(n/p);
    }
    void solve(LL a)
    {
        if(a==1)
        {
            printf("is not a D_num
    ");
            return;
        }
        t=0;
        factor(a);
        sort(Factor,Factor+t);
        if(t==2)
        {
            if(Factor[0]!=Factor[1])
            {
                printf("%I64d %I64d %I64d
    ",Factor[0],Factor[1],a);
            }
            else
                printf("is not a D_num
    ");
        }
        else if(t==3)
        {
            if(Factor[0]==Factor[1]&&Factor[1]==Factor[2])
                printf("%I64d %I64d %I64d
    ",Factor[0],Factor[0]*Factor[1],a);
            else printf("is not a D_num
    ");
        }
        else printf("is not a D_num
    ");
    }
    int main()
    {
        LL a;
        while(~scanf("%I64d",&a))
        {
            solve(a);
        }
        return 0;
    }
    


  • 相关阅读:
    HDU 1160 dp中的路径问题
    zzuli 1907: 小火山的宝藏收益
    POJ 3414 dfs广搜直接应用
    http://acm.zzuli.edu.cn/zzuliacm/problem.php?cid=1158&pid=5 二分函数的间接应用
    LightOJ 1067 组合数取模
    九段美到极致的句子
    质数和分解
    codevs 1080 线段树练习
    codevs 2806 红与黑
    codevs 2152 滑雪
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5141846.html
Copyright © 2020-2023  润新知