Miller-Rabin及Pollard-Rho算法学习小记

来源:互联网 发布:折800被淘宝封了 编辑:程序博客网 时间:2024/04/30 00:50

质数快速判断算法Miller-Rabin

不想详细写了,因为也不会证。
贴板子!

bool Miller_Rabin(ll n){    if (n==1) return 0;    int s=5,t=0,i;    ll a,p,k=n-1;    while (k%2==0) k/=2,t++;    while (s--){        a=random(n-1)+1;        p=a=qsm(a,k,n);        fo(i,1,t){            a=mul(a,a,n);            if (a==1&&p!=1&&p!=n-1) return 0;            p=a;        }        if (a!=1) return 0;    }    return 1;}

因数快速分解算法Pollard-Rho

不想详细写了,因为也不会证。
贴板子!

ll Pollard_Rho(ll n){    ll k,x,y,c,d,i=1;    while (1){        c=random(n-1);        k=2;y=x=random(n);        i=1;        while (1){            y=(mul(y,y,n)+c)%n;            d=gcd(abs(x-y),n);            if (i==k) x=y,k<<=1;            i++;            if (d!=1) break;        }        if (d!=n) return d;    }}

BZOJ3667

裸题

#include<cstdio>#include<algorithm>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;typedef long long ll;int i,j,k,l,t,m,ca;ll n,ans;ll random(ll x){    ll t=rand()%10000;    t=t*10000+rand()%10000;    t=t*10000+rand()%10000;    t=t*10000+rand()%10000;    return t%x;}ll mul(ll a,ll b,ll p){    ll tmp=(a*b-(ll)((long double)a/p*b+1e-8)*p);    return tmp<0?tmp+p:tmp;}ll qsm(ll x,ll y,ll mo){    if (!y) return 1;    ll t=qsm(x,y/2,mo);    t=mul(t,t,mo);    if (y%2) t=mul(t,x,mo);    return t;}bool Miller_Rabin(ll n){    if (n==1) return 0;    int s=5,t=0,i;    ll a,p,k=n-1;    while (k%2==0) k/=2,t++;    while (s--){        a=random(n-1)+1;        p=a=qsm(a,k,n);        fo(i,1,t){            a=mul(a,a,n);            if (a==1&&p!=1&&p!=n-1) return 0;            p=a;        }        if (a!=1) return 0;    }    return 1;}ll gcd(ll a,ll b){    return b?gcd(b,a%b):a;}ll Pollard_Rho(ll n){    ll k,x,y,c,d,i=1;    while (1){        c=random(n-1);        k=2;y=x=random(n);        i=1;        while (1){            y=(mul(y,y,n)+c)%n;            d=gcd(abs(x-y),n);            if (i==k) x=y,k<<=1;            i++;            if (d!=1) break;        }        if (d!=n) return d;    }}void work(ll n){    if (Miller_Rabin(n)){        ans=max(ans,n);        return;    }    ll p=Pollard_Rho(n);    ll q=n/p;    work(p);work(q);}int main(){    srand(19890604);    scanf("%d",&ca);    while (ca--){        scanf("%lld",&n);        ans=0;        work(n);        if (ans==n) printf("Prime\n");else printf("%lld\n",ans);    }}
0 0
原创粉丝点击