POJ1811 miller-rabin素数测试pollard-rho质因子分解

这道题太综合了 运用了挺多知识的综合题 做了一天 才发现没有充分的运用乘法取模函数 这题用了miller-rabin素数随机性素数测试方法

pollard-rho方法 这两个理论性都很强 我也是看算法导论学的 还有这题用到 rand() 随机函数 之所以这么研究这道题就是为了以后的比赛的时候这种问题可以作为模板了 素数的测试 合数的质因子分解 a*b%n  a^b%n 最起码四个模板了 

 

#include <iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long int64;
int64 gcd(int64 a,int64 b)
{
    if (a==0) return 1;
    if(a<0) return gcd(-a,b);
    if(b==0) return a;
    return gcd(b,a%b);
}
int64 modmult(int64 a,int64 b,int64 n)//a*b%n
{
    a%=n;
    int64 ret;
    for(ret=0; b; a=(a<<1)%n,b>>=1)
        if(b&1)
            ret=(ret+a)%n;
    return ret;
}
int64 modular(int64 a,int64 b,int64 n)//renturn a^b%n
{
    int64 ans=1;
    a%=n;
    while(b)
    {
        if(b&1)
            ans=modmult(ans,a,n),b--;
        b>>=1;
        a=modmult(a,a,n);
    }
    return ans;
}
bool witness(int64 a,int64 n)//判断 a^(n-1)=1(mod n)
{
    int t=0;
    int64 x,xi,temp=n-1;
    while(temp%2==0)
        t++,temp/=2;
    xi=x=modular(a,temp,n);
    for(int i=1; i<=t; i++)
    {
        xi=modmult(xi,xi,n);
        if(xi==1&&x!=1&&x!=n-1)
            return 1;
        x=xi;
    }
    if(xi!=1)
        return 1;
    return 0;
}
bool millar_rabin(int64 n,int s)
{
    for(int j=1; j<=s; j++)
    {
        int64 a=rand()%(n-1)+1;//a=rand()%(Y-X+1)+X; /*n为X~Y之间的随机数
        if(witness(a,n))
            return 0;
    }
    return 1;
}
int64 pollard_rho(int64 n,int64 c)
{
    int64 i=1,k=2,x,y;
    x=rand()%n;
    y=x;
    while(1)
    {
        i++;
        x=(modmult(x,x,n)+c)%n;
        int64 d=gcd(y-x,n);
        if(d!=1&&d!=n)
            return d;
        if(x==y)
            return n;
        if(i==k)
        {
            y=x;
            k+=k;
        }
    }
}
int64 factor[100];
int tol;
void findfac(int64 n)
{
    if(millar_rabin(n,10))
    {
        factor[tol++]=n;
        return;
    }
    int64 p=n;
    while(p>=n)
        p=pollard_rho(p,rand()%(n-1)+1);
    findfac(p);
    findfac(n/p);
}
int main()
{
    int64 n;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld",&n);
        if(millar_rabin(n,10))
        {
            printf("Prime\n");
            continue;
        }
        tol=0;
        findfac(n);
        sort(factor,factor+tol);
        printf("%lld\n",factor[0]);
    }
    return 0;
}
时间: 2025-01-29 14:53:25

POJ1811 miller-rabin素数测试pollard-rho质因子分解的相关文章

POJ2429 Pollard rho因子分解

题意给出最大公约数和最小公倍数,让求出满足这个条件的两个数并且该两个数的和最小.并按照从小到大的顺序输出.因子分解用的是Pollard rho启发式方法 首先给出了gcd lcm,令两个数为ansm*gcd ansn*gcd,那么lcm=(ansm*gcd)*(ansn*gcd)/gcd=ansm*gcd*ansn,那么ansn*ansm=lcm/gcd,所以将lcm/gcd进行因子分解所得到的因子一部分乘积为ansm,那么剩下的就是ansn,并且ansn ansm互素(如果不互素那么两个数的最

POJ 2992 质因子分解

题意要求出C(n,k)的因子个数 所以就需要把C(n,k)质因子分解 这题数据非常变态 我的思路没问题但是无数次TLE之后我才发现应该先打出一个 n!的一个表 不然就超时 用C(n,k)=n!/(k!*(n-k)!) 这个公式就可以求出 #include <iostream> #include<cstdio> #include<cstring> using namespace std; #define max 435 int prime[max],nprime; boo

【算法编程】基于Miller-Rabin的大素数测试

基本原理: 费尔马小定理:如果p是一个素数,且0<a<p,则a^(p-1)%p=1.       利用费尔马小定理,对于给定的整数n,可以设计素数判定算法,通过计算d=a^(n-1)%n来判断n的素性,当d!=1时,n肯定不是素数,当d=1时,n  很可能是素数. 二次探测定理:如果p是一个素数,且0<x<p,则方程x^2%p=1的解为:x=1或x=p-1.       利用二次探测定理,可以再利用费尔马小定理计算a^(n-1)%n的过程中增加对整数n的二次探测,一旦发现违背二次探

HDU 3864 pollard_rho大数质因子分解

题意:给你一个大数n,问有恰好有4个m满足Gcd(N, M) == M,从小到大输出大于1时的M. 这题就是问N是否有4个因子,除去1和N本身有两个因子,将N分解成质因子的形式,可以是一个素数的立方也可以是两个素数相乘. #include <iostream> #include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; typedef long long int64;

代码-如何解决大素数分解问题??

问题描述 如何解决大素数分解问题?? 用C++写了一个分解大素数的代码,结果却出来这样的结果,请问是怎么回事??该如何解决?? 输入数据:1801440097841710589 GNU MP: Cannot reallocate memory This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for

求解素数几种方法

转贴文章请注明:逸学堂   求解一个算法,我们首先要知道它的数学含义.依据这个原则,首先我们要知道什么是素数.; 素数是这样的整数,它除了表示为它自己和1的乘积以外,无论他表示为任何两个整数的乘积. 找素数的方法多种多样. 1:是从2开始用"是则留下,不是则去掉"的方法把所有的数列出来(一直列到你不想再往下列为止,比方说,一直列到10,000).第一个数是2,它是一个素数,所以应当把它留下来,然后继续往下数,每隔一个数删去一个数,这样就能把所有能被2整除.因而不是素数的数都去掉.在留下

Miller-Rabin素性测试(POJ3641)

一.概念引入         在以往判断一个数n是不是素数时,我们都是采用i从2到sqrt(n)能否整除n.如果能整除,则n是合数;否则是素数.但是该算法的时间复杂度为O(sqrt(n)),当n较大时,时间性能很差,特别是在网络安全和密码学上一般都是需要很大的素数.而从目前来看,确定性算法判断素数的性能都不好,所以可以用MC(蒙特卡洛)概率算法来解决,其中Miller Rabin算法就是其中的很经典的解决方法.下面首先介绍下相关的数学理论.         理论基础:Fermat小定理:若n是素

如何测试电脑超频是否稳定?

1.计算高位圆周率的时间有多长 Superπ superπ是由日本东京大学金田研究室开发的一款用来计算圆周率的软件,设计者的初衷当初只是在HITAC S-3800/480超级计算机上使用,由于在计算π值时,考验到了CPU的多方面计算能力,因此后来被日本的超频爱好者移植到PC上使用,借助Superπ来测试超频后的性能,后来慢慢传入我国,许多硬件实验室也使用这款软件作为测试CPU稳定性的依据. 运行程序时,点击"运行计算"按钮,此时会弹出一个对话框请你选择要运行的圆周率位数,一般采用104

一款类似的肌肤测试硬件进入市场,这次它叫做“脸蛋”

摘要: 大约一年前, 36氪 报道过一款酷似珠宝的皮肤测量仪微蜜,通过耳机接口同手机相连,把微蜜贴到脸上,就能在APP上看到皮肤含水量的测试结果.当时,微蜜走的是导购路线,计划同欧 大约一年前,36氪报道过一款酷似珠宝的皮肤测量仪"微蜜",通过耳机接口同手机相连,把"微蜜"贴到脸上,就能在APP上看到皮肤含水量的测试结果.当时,微蜜走的是导购路线,计划同欧莱雅等护肤品厂商合作,给用户做护肤品推荐和提醒. 而在几乎相同时间点,LVMH集团旗下的美容产品零售商丝芙兰(S