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\n");
        else
        {
            //rhoAll(n);
            printf("%I64d\n",rho(n));
        }
        /*for(int i=0;i<flag;i++) //输出全部质因子
            if(i!=flag-1)
                printf("%I64d ",ans[i]);
            else
                printf("%I64d\n",ans[i]);*/
    }
    return 0;
}
时间: 2024-11-07 13:26:48

POJ 1811 大素数判断的相关文章

csu 1552: Friends(大素数判断+二分图)

1552: Friends Time Limit: 3 Sec  Memory Limit: 256 MB Submit: 525  Solved: 136 [Submit][Status][Web Board] Description On an alien planet, every extraterrestrial is born with a number. If the sum of two numbers is a prime number, then two extraterres

大素数判断和素因子分解【miller-rabin和Pollard_rho算法】

集训队有人提到这个算法,就学习一下,如果用到可以直接贴模板,例题:POJ 1811 转自:http://www.cnblogs.com/kuangbin/archive/2012/08/19/2646396.html 传说中的随机算法. 效率极高. 可以对一个2^63的素数进行判断. 可以分解比较大的数的因子. 1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<time

大素数判断和素因子分解(miller-rabin,Pollard_rho算法)

#include<stdio.h> #include<string.h> #include<stdlib.h> #include<time.h> #include<iostream> #include<algorithm> using namespace std; //**************************************************************** // Miller_Rabin 算法进

Prime Test POJ - 1811(素性检测+大数分解)

Prime Test POJ - 1811 题意:判断N (2 <= N < 2 54) 是不是素数,如果不是求它的最小素因数. millerRabin素性检测 + pollard rho大数分解 链接 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 #define LL l

POJ 2262 Goldbach&#39;s Conjecture (素数判断)

Goldbach's Conjecture Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 37693   Accepted: 14484 Description In 1742, Christian Goldbach, a German amateur mathematician, sent a letter to Leonhard Euler in which he made the following conject

数学#素数判定Miller_Rabin+大数因数分解Pollard_rho算法 POJ 1811&amp;2429

素数判定Miller_Rabin算法详解: http://blog.csdn.net/maxichu/article/details/45458569 大数因数分解Pollard_rho算法详解: http://blog.csdn.net/maxichu/article/details/45459533 然后是参考了kuangbin的模板: http://www.cnblogs.com/kuangbin/archive/2012/08/19/2646396.html 模板如下: //快速乘 (a

poj 2689 大范围内素数筛选

1 /** 2 给定一定范围求其内的素数 3 4 注意: 5 **/ 6 7 #include <iostream> 8 #include <math.h> 9 #include <cstring> 10 using namespace std; 11 #define maxn 1000000 12 long long prime[500000]; 13 long long cprime[500000]; 14 long long isprime[maxn+100];

poj 1811, poj 2429 (pollard_rho算法)

poj 1811 题意: 给出一个整数n,判断n是不是素数,如果不是素数,输出最小的质因子. 限制: 2 <= N < 2^54 思路: miller_rabin算法判素数 pollard_rho算法求质因子 复杂度O(log(n)) poj 2429 题意: 给出两个数的lcm和gcd,求这两个数. 限制: 0 < lcm,gcd < 2^63 思路: pollard_rho O(log(n))分解质因数. 可以考虑到2^63不同的质因数只有20左右个,而相同的质数不可能分在不同

数论快速入门(同余、扩展欧几里德、中国剩余定理、大素数测定和整数分解、素数三种筛法、欧拉函数以及各种模板)

数学渣渣愉快的玩了一把数论,来总结一下几种常用的算法入门,不过鶸也是刚刚入门, 所以也只是粗略的记录下原理,贴下模板,以及入门题目(感受下模板怎么用的) (PS:文中蓝色字体都可以点进去查看百度原文) 附赠数论入门训练专题:点我打开专题(题目顺序基本正常,用以配套数论入门) 一.同余定理 简单粗暴的说就是:若 a-b == m 那么 a%m == b%m 这个模运算性质一眼看出...直接上入门水题: Reduced ID Numbers 附AC代码(这个也没啥模板....知道就好) #inclu