模板题Pollard_Rho大数分解 A - Prime Test POJ - 1811

题意:是素数就输出Prime,不是就输出最小因子.

复制代码
#include <cstdio>
#include<time.h>
#include <algorithm>
#include<set>
using namespace std;

typedef long long llt;

int const Repeat = 10;
set<llt>sss;
//利用二进制计算a*b%mod
llt multiMod(llt a, llt b, llt mod){
    llt ret = 0LL;
    a %= mod;
    while (b){
        if (b & 1LL) ret = (ret + a) % mod, --b;
        b >>= 1LL;
        a = (a + a) % mod;
    }
    return ret;
}

//计算a^b%mod
llt powerMod(llt a, llt b, llt mod){
    llt ret = 1LL;
    a %= mod;
    while (b){
        if (b & 1LL) ret = multiMod(ret, a, mod), --b;
        b >>= 1LL;
        a = multiMod(a, a, mod);
    }
    return ret;
}

//Miller-Rabin测试,测试n是否为素数
bool Miller_Rabin(llt n, int repeat){
    if (2LL == n || 3LL == n) return true;
    if (!(n & 1LL)) return false;

    //将n分解为2^s*d
    llt d = n - 1LL;
    int s = 0;
    while (!(d & 1LL)) ++s, d >>= 1LL;

    //srand((unsigned)time(0));
    for (int i = 0; i<repeat; ++i){//重复repeat次
        llt a = rand() % (n - 3) + 2;//取一个随机数,[2,n-1)
        llt x = powerMod(a, d, n);
        llt y = 0LL;
        for (int j = 0; j<s; ++j){
            y = multiMod(x, x, n);
            if (1LL == y && 1LL != x && n - 1LL != x) return false;
            x = y;
        }
        if (1LL != y) return false;
    }
    return true;
}

llt Fac[100];//质因数分解结果(刚返回时是无序的)
int FCnt;//质因数的个数。数组小标从0开始

llt gcd(llt a, llt b){
    if (0L == a || 0L == b) return 1;
    if (a < 0) a = -a;
    if (b < 0) b = -b;
    while (b){
        llt t = a % b;
        a = b;
        b = t;
    }
    return a;
}
llt Pollard_Rho(llt n, llt c){
    llt i = 1, k = 2;
    llt x = rand() % n;
    llt y = x;
    while (1){
        ++i;
        x = (multiMod(x, x, n) + c) % n;
        llt d = gcd(y - x, n);
        if (d != 1LL && d != n) return d;
        if (y == x) return n;
        if (i == k) y = x, k <<= 1;
    }
}

void find(llt n){
    if (4LL == n){
        Fac[0] = Fac[1] = 2LL;
        FCnt = 2;
        return;
    }
    if (Miller_Rabin(n, Repeat)){
        Fac[FCnt++] = n;
        return;
    }

    llt p;
    while ((p = Pollard_Rho(n, rand() % (n - 3) + 3)) == n);

    find(p);
    find(n / p);
}

int main(){
    int kase;
    scanf("%d", &kase);
    while (kase--){
        llt n;
        scanf("%lld", &n);

        FCnt = 0;
        if (Miller_Rabin(n, 10)){ printf("Prime\n"); }
        else{
            find(n);
            llt ans = Fac[0];
            for (int i = 0; i < FCnt;++i)
            if (ans>Fac[i])ans = Fac[i];
            printf("%lld\n", ans);
        }
    }
    return 0;
}
复制代码

 

作者:ALINGMAOMAO

出处:https://www.cnblogs.com/ALINGMAOMAO/p/9833304.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   青山新雨  阅读(273)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
more_horiz
keyboard_arrow_up light_mode palette
选择主题
点击右上角即可分享
微信分享提示