POJ 1811 Prime Test

来源:互联网 发布:中国淘宝第一村大集镇 编辑:程序博客网 时间:2024/06/12 01:45

时空隧道


题意:
给出一个数n,判断n是否为素数,如果n不是素数输出n的最小素因子…(多组数据,n<=2^54)


分析:
MillerRabin素性测试+PollardRho椭圆曲线分解法
算法讲解


Notice:

  • 两数相乘可能会爆 long long,所以要自己手写乘法

代码如下:

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>//by NeighThornusing namespace std;long long Min;inline long long random(long long n){    return ((double)rand()/RAND_MAX*n+0.5);}inline long long multiply(long long a,long long b,long long mod){    long long ans=0;    while(b){        if(b&1)            b--,ans=(ans+a)%mod;        else            b>>=1,a=(a*2)%mod;     }    return ans;}inline long long power(long long a,long long b,long long mod){    long long ans=1;    while(b){        if(b&1)            ans=multiply(ans,a,mod)%mod;        a=multiply(a,a,mod)%mod,b>>=1;    }    return ans;}inline bool check(long long a,long long n){    long long d=n-1;    while(!(d&1))        d>>=1;    long long t=power(a,d,n);    while(d!=n-1&&t!=n-1&&t!=1)        t=multiply(t,t,n)%n,d<<=1;    return t==n-1||d&1;}inline bool MillerRabin(long long n){    if(n==2)        return true;    if(n<2||!(n&1))         return false;    for(int i=1;i<=10;i++)        if(!check(random(n-2)+1,n))            return false;    return true;}inline long long gcd(long long x,long long y){    return y==0?x:gcd(y,x%y);}inline long long PollardRho(long long n,int c){    long long x,y,d,i=1,k=2;    x=random(n-2)+1,y=x;    while(1){        i++;x=(multiply(x,x,n)+c)%n;d=gcd(y-x,n);        if(1<d&&d<n)            return d;        if(y==x)            return n;        if(i==k)            y=x,k<<=1;    }}inline void find(long long n,int c){    if(n==1)        return;    if(MillerRabin(n)){        Min=min(Min,n);        return;    }    long long p=n;    while(p>=n)        p=PollardRho(p,c--);    find(p,c);find(n/p,c);}signed main(void){    int cas;long long n;    scanf("%d",&cas);    while(cas--){        scanf("%lld",&n);        Min=n;        if(MillerRabin(n))            puts("Prime");        else            find(n,12312),cout<<Min<<endl;    }    return 0;}

by >_< NeighThorn

1 0
原创粉丝点击