Pollard_Rho大数分解模板题 pku-2191

本文介绍了一种基于米勒拉宾素性测试与Pollard_Rho大数分解算法的程序实现,用于解决特定数学问题:给定一个整数n,求所有形如2^k-1(k为素数且小于等于n)的合数及其质因数分解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给你一个数n,  定义m=2k-1,   {k|1<=k<=n},并且 k为素数;  当m为合数时,求分解为质因数,输出格式如下:47 * 178481 = 8388607 = ( 2 ^ 23 ) - 1  

分析:要分解m,首先要判断m是否为合数,直接用米勒拉宾判断,但是后面的大合数分解,一开始用了试除法,直接给超时。所以,有更加快速的方法。(现学的)。使用Pollard_Rho大数分解算法。  

Pollard_Rho大数分解时间复杂度为n1/4 

ac代码:

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

typedef long long llt;

int const Repeat = 10;
const int N = 105;
int prime[N];
bool vis[N], is_prime[N];
//利用二进制计算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 Prime()
{
    int cnt = 0;
    for (int i = 2; i <= N; ++i)
    {
        if (!vis[i])
        {
            prime[cnt++] = i;    is_prime[i] = 1;
        }
        for (int j = 0; j < cnt&&i*prime[j] <= N; ++j)
        {
            vis[i*prime[j]] = 1;
            if (i%prime[j] == 0)break;
        }
    }
    return cnt;
}

llt poww(llt x, llt n)
{
    llt res = 1;
    for (; n;x=x*x, n>>=1)
    if (n & 1)res = res*x;
    return res;
}
int main()
{
    int k = Prime();
    llt n;
    while (scanf("%lld", &n) != EOF)
    {
        for (int i = 0; prime[i] <= n; ++i)
        {
            llt pnum = poww(2, prime[i]) - 1;
            if (!Miller_Rabin(pnum, 5))
            {
                FCnt = 0;
                find(pnum);
                sort(Fac, Fac + FCnt);
                printf("%lld", Fac[0]);
                for (int i = 1; i < FCnt; ++i)
                    printf(" * %lld", Fac[i]);
                printf(" = %lld = ( 2 ^ %d ) - 1\n", pnum, prime[i]);
            }
        }
    }
}

 

转载于:https://www.cnblogs.com/ALINGMAOMAO/p/9674274.html

内容概要:本文深入探讨了Kotlin语言在函数式编程和跨平台开发方面的特性和优势,结合详细的代码案例,展示了Kotlin的核心技巧和应用场景。文章首先介绍了高阶函数和Lambda表达式的使用,解释了它们如何简化集合操作和回调函数处理。接着,详细讲解了Kotlin Multiplatform(KMP)的实现方式,包括共享模块的创建和平台特定模块的配置,展示了如何通过共享业务逻辑代码提高开发效率。最后,文章总结了Kotlin在Android开发、跨平台移动开发、后端开发和Web开发中的应用场景,并展望了其未来发展趋势,指出Kotlin将继续在函数式编程和跨平台开发领域不断完善和发展。; 适合人群:对函数式编程和跨平台开发感兴趣的开发者,尤其是有一定编程基础的Kotlin初学者和中级开发者。; 使用场景及目标:①理解Kotlin中高阶函数和Lambda表达式的使用方法及其在实际开发中的应用场景;②掌握Kotlin Multiplatform的实现方式,能够在多个平台上共享业务逻辑代码,提高开发效率;③了解Kotlin在不同开发领域的应用场景,为选择合适的技术栈提供参考。; 其他说明:本文不仅提供了理论知识,还结合了大量代码案例,帮助读者更好地理解和实践Kotlin的函数式编程特性和跨平台开发能力。建议读者在学习过程中动手实践代码案例,以加深理解和掌握。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值