[POJ]1811Prime Test 做题笔记

1 篇文章 0 订阅

题目来源:http://poj.org/problem?id=1811
这题是miller_rabbin素数测试 + pollar_rho
所用的miller_rabbin貌似不止用了费马小定理,还用了一个不知名的定理,但如果像某些写法中,把miller_rabbin函数中的if (!Judge(a,n)) return 0;改成if (modular_exp(a,n-1,n)!=1) return 0;则会直接WA,虽然之前水CodeVS2849时这么写就没有问题。。
pollard rho算法思想可以在Pollard rho算法详解看一下

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
int T;ll n,minx;
ll multi (ll x,ll y,ll mod) {
    ll ans=0;
    x%=mod;
    for (;y;y>>=1,x=(x<<1)%mod)
        if (y&1) ans=(ans+x)%mod;
    return ((ans+mod)%mod);
}
ll modular_exp (ll x,ll p,ll mod) {
    ll ans=1;
    x%=mod;
    for (;p;p>>=1,x=multi(x,x,mod)) 
        if (p&1) ans=multi(ans,x,mod);
    return ((ans+mod)%mod);
}
bool Judge (ll a,ll n)
{
    ll d=n-1;
    while (!(d&1)) d>>=1;
    ll t=modular_exp(a,d,n);
    while (d!=n-1&&t!=1&&t!=n-1)
        t=multi(t,t,n),d<<=1;
    return t==n-1||d&1;
}
bool miller_rabbin (ll n) {
    if (n==2) return 1;
    if (n<2||!(n&1)) return 0;
    ll a;
    for (int i=0;i<10;i++) {
        a=rand()%(n-2)+2;
        if (!Judge(a,n)) return 0;
    }
    return 1;
}
ll gcd (ll a,ll b) {
    if (a==0) return 1;//?
    if (!b) return a;
    return gcd(b,a%b);
}
ll pollard_rho (ll a,ll c) {
    ll i=1,k=2,x=rand()%a;ll y=x;
    while (1) {
        i++; x=(multi(x,x,a)+c)%a;
        ll d=gcd((ll)fabs(y-x),a);
        if (d!=1&&d!=a) return d;
        if (y==x) return a;
        if (i==k) y=x,k<<=1;
    }
}
void findfac (ll n) {
    if (n==1) return ;//
    if (miller_rabbin(n)) {
        minx=min(minx,n);
        return ;
    }
    ll p=n;
    while (p>=n) p=pollard_rho(p,rand()%(n-1)+1);
    findfac(p);findfac(n/p);
}
int main () {
    srand(233);
    scanf("%d",&T);
    while (T--) {
        scanf("%lld",&n);minx=n;
        if (miller_rabbin(n)) puts("Prime");
        else {
            findfac(n);
            printf("%lld\n",minx);
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值