Miller_Rabbin&&Pollard_Rho

前言

Miller Rabin 算法是一种高效的质数判断方法。虽然是一种不确定的质数判断法,但是在选择多种底数的情况下,正确率是可以接受的。

Pollard Rho是一个非常玄学的方式,用于在\(O(n^\frac{1}{4})\)的期望时间复杂度内计算合数\(n\)的某个非平凡因子。事实上算法导论给出的是\(O(\sqrt{p})\)\(p\)\(n\)的某个最小因子,满足\(p\)\(n/p\)互质。但是这些都是期望,未必符合实际。但事实上Pollard Rho算法在实际环境中运行的相当不错。

Miller_Rabbin算法

题目:LOJ #143. 质数判定

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int p[10]={2,3,5,7,11,13,17,19,61,24251};
LL quick(LL a,LL b,LL mod)
{
    LL res=1;
    while(b)
    {
        if(b&1)res=((__int128)res*a)%mod;
        a=((__int128)a*a)%mod;
        b>>=1;
    }
    return res;
}
bool mr(LL x,LL b)
{
    LL k=x-1;
    while(k)
    {
        LL cur=quick(b,k,x);
        if(cur!=1&&cur!=x-1)return false;
        if((k&1)||cur==x-1)return true;
        k>>=1;
    }
    return true;
}
bool prime(LL x)
{
    if(x==1)return false;
    for(int i=0;i<10;i++)
    {
        if(x==p[i])return true;
        if(!mr(x,p[i]))return false;
    }
    return true;
}
int main()
{
    LL x;
    while(~scanf("%lld",&x))
    {
        if(prime(x))printf("Y\n");
        else printf("N\n");
    }
    return 0;
}

Pollard_Rho算法

题目:P4718 【模板】Pollard-Rho算法

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef __int128 LLL;
LL maxfac;
int p[10]={2,3,5,7,11,13,17,19,61,24251};
LL gcd(LL a,LL b)
{
    return b==0?a:gcd(b,a%b);
}
LL quick(LL a,LL b,LL mod)
{
    LL res=1;
    while(b)
    {
        if(b&1)res=((LLL)res*a)%mod;
        a=((LLL)a*a)%mod;
        b>>=1;
    }
    return res;
}
bool mr(LL x,LL b)
{
    LL k=x-1;
    while(k)
    {
        LL cur=quick(b,k,x);
        if(cur!=1&&cur!=x-1)return false;
        if((k&1)||cur==x-1)return true;
        k>>=1;
    }
    return true;
}
bool prime(LL x)
{
    if(x==1)return false;
    for(int i=0;i<10;i++)
    {
        if(x==p[i])return true;
        if(!mr(x,p[i]))return false;
    }
    return true;
}
LL PR(LL x)
{
    LL s=0,t=0,c=1LL*rand()%(x-1)+1;
    for(int goal=1;;goal<<=1)
    {
        s=t;
        LL val=1;
        for(int stp=1;stp<=goal;stp++)
        {
            t=((LLL)t*t+c)%x;
            val=(LLL)val*abs(t-s)%x;
            if(stp%127==0)
            {
                LL d=gcd(val,x);
                if(d>1)return d;
            }
        }
        LL d=gcd(val,x);
        if(d>1)return d;
    }
}
void fac(LL x)
{
    if(x<=maxfac||x<2)return;
    if(prime(x))
    {
        maxfac=x;
        return;
    }
    LL p=x;
    while(p>=x)p=PR(x);
    while(x%p==0)x/=p;
    fac(x);fac(p);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        srand((unsigned)time(NULL));
        LL x;
        scanf("%lld",&x);
        maxfac=0;
        fac(x);
        if(maxfac==x)printf("Prime\n");
        else printf("%lld\n",maxfac);
    }
}
posted @ 2020-03-12 00:08  灰灰烟影  阅读(158)  评论(0编辑  收藏  举报