首页 > 其他 > 详细

Miller-Rabin,Pollard-Rho(BZOJ3667)

时间:2017-01-18 16:20:37      阅读:343      评论:0      收藏:0      [点我收藏+]

裸题直接做就好了。

#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;

typedef long long ll;
const int p[]={2,3,5,7,11,13,17,19,23};
int T;
ll n,mx;

ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll mul(ll a,ll b,ll p) {
    ll r=a*b-(ll)((long double)a/p*b+1e-8)*p;
    return r<0?r+p:r;
}
ll qp(ll a,ll b,ll p) {
    ll r=1;
    for(;b;b>>=1,a=mul(a,a,p)) if(b&1) r=mul(r,a,p);
    return r;
}
bool chk(ll a,ll n,ll r,ll s) {
    ll x=qp(a,r,n),pre=x;
    for(int i=1;i<=s;i++,pre=x) {
        x=mul(x,x,n);
        if(x==1&&pre!=1&&pre!=n-1) return 0;
    }
    return x==1;
}
bool mr(ll n) {
    ll r=n-1,s=0;
    while(!(r&1)) r>>=1,s++;
    for(int i=0;i<9;i++) {
        if(p[i]==n) return 1;
        if(!chk(p[i],n,r,s)) return 0;
    }
    return 1;
}
ll po(ll n,ll a) {
    for(ll i=1,k=2,x=rand()%n,y=x;;i++) {
        x=(mul(x,x,n)+a)%n;
        if(gcd(n,abs(y-x))^1) return gcd(n,abs(y-x));
        if(i==k) y=x,k<<=1;
    }
}
void sol(ll n) {
    if(n==1) return;
    if(mr(n)) {mx=max(mx,n); return;}
    ll t=n;
    while(t==n) t=po(n,rand()%n);
    sol(t),sol(n/t);
}

int main() {
    srand(819733672);
    scanf("%d",&T);
    while(T--) {
        scanf("%lld",&n),mx=0,sol(n);
        if(mx==n) puts("Prime"); else printf("%lld\n",mx);
    }
    return 0;
}

Miller-Rabin,Pollard-Rho(BZOJ3667)

原文:http://www.cnblogs.com/juruolty/p/6296867.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!