zoukankan      html  css  js  c++  java
  • POJ 1811 大素数判断

    数据范围很大,用米勒罗宾测试和Pollard_Rho法可以分解大数。

    模板在代码中 O.O

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    
    __int64 pri[]= {2,3,5,7,11,13,17,19,23,29,31};//用小素数表做随机种子避免第一类卡米歇尔数的误判
    __int64 multi(__int64 a,__int64 b,__int64 n) //乘法快速幂
    {
        __int64 tmp=0;
        while(b)
        {
            if(b&1)
            {
                tmp+=a;
                if(tmp>=n) tmp-=n;
            }
            a<<=1;
            if(a>=n) a-=n;
            b>>=1;
        }
        return tmp;
    }
    __int64 multimod(__int64 a,__int64 m,__int64 n) //乘法快速幂
    {
        __int64 tmp=1;
        a%=n;
        while(m)
        {
            if(m&1) tmp=multi(tmp,a,n);
            a=multi(a,a,n);
            m>>=1;
        }
        return tmp;
    }
    __int64 gcd(__int64 a, __int64 b)        //迭代算法
    {
        while(b)
        {
           __int64 c=a%b;
           a=b;
           b=c;
        }
        return a;
    }
    bool Miller_Rabin(__int64 n) //大素数判断
    {
        if(n<2)
            return false;
        if(n==2)
            return true;
        if(!(n&1))
            return false;
        __int64 k=0,j,m,a;
        m=n-1;
        while(!(m&1))
        {
            m>>=1;
            k++;
        }
        for(int i=0; i<10; i++)
        {
            if(pri[i]>=n)
                return true;
            a=multimod(pri[i],m,n);
            if(a==1)
                continue;
            for(j=0; j<k; j++)
            {
                if(a==n-1)
                    break;
                a=multi(a,a,n);
            }
            if(j==k)
                return false;
        }
        return true;
    }
    __int64 pollard_rho(__int64 c,__int64 n) //查找因数
    {
        __int64 i,x,y,k,d;
        i=1;
        x=y=rand()%n;
        k=2;
        do
        {
            i++;
            d=gcd(n+y-x,n);
            if(d>1 && d<n)
                return d;
            if(i==k)
            {
                y=x;
                k<<=1;
            }
            x=(multi(x,x,n)+n-c)%n;
        }
        while(y!=x);
        return n;
    }
    __int64 rho(__int64 n)
    {
        if(Miller_Rabin(n))
            return n;
        __int64 t=n;
        while(t>=n)
            t=pollard_rho(rand()%(n-1)+1,n);
        __int64 a=rho(t);
        __int64 b=rho(n/t);
        return a<b? a:b;
    }
    
    __int64 ans[10000005],flag;
    void rhoAll(__int64 n) //计算全部质因子
    {
        if(Miller_Rabin(n))
        {
            ans[flag++]=n;
            return;
        }
        __int64 t=n;
        while(t>=n)
            t=pollard_rho(rand()%(n-1)+1,n);
        rhoAll(t);
        rhoAll(n/t);
        return;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int t;
        __int64 n;
        scanf("%d",&t);
        while(t--)
        {
            flag=0;
            scanf("%I64d",&n);
            if(Miller_Rabin(n))
                printf("Prime
    ");
            else
            {
                //rhoAll(n);
                printf("%I64d
    ",rho(n));
            }
            /*for(int i=0;i<flag;i++) //输出全部质因子
                if(i!=flag-1)
                    printf("%I64d ",ans[i]);
                else
                    printf("%I64d
    ",ans[i]);*/
        }
        return 0;
    }
  • 相关阅读:
    Python学习日志(三)
    Python学习日志(二)
    软件测试入门随笔——软件测试基础知识(八)
    软件测试入门随笔——软件测试基础知识(七)
    软件测试入门随笔——软件测试基础知识(六)
    fastcgi 性能初配 504 gateway time-out
    php 文件锁
    php sleep()的实时输出打印,清除ob缓冲区
    php用simplexml来操作xml
    PHP防SQL注入不要再用addslashes和mysql_real_escape_string
  • 原文地址:https://www.cnblogs.com/pach/p/6028539.html
Copyright © 2011-2022 走看看