梅森素数(Mersenne prime)判断, FFT 大数乘法 (非递归), O(n^2 log n), c++

本文介绍了如何运用快速傅里叶变换(FFT)算法实现大数乘法,以此优化卢卡斯-莱默检验法来判断梅森素数。详细阐述了FFT的工作原理,并给出了一个n=8的实例来说明其计算过程。同时讨论了如何选择根w以避免浮点数运算,特别针对2的幂次寻找满足条件的模数MOD。

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

原创代码,请勿转载!

梅森素数判定:
卢卡斯-莱默检验法:参考https://zh.wikipedia.org/wiki/%E5%8D%A2%E5%8D%A1%E6%96%AF-%E8%8E%B1%E9%BB%98%E6%A3%80%E9%AA%8C%E6%B3%95


卢卡斯-莱默检验法 是迭代算法,需要用到高精度乘法运算。
而现有的乘法运算算法最快的要数 快速傅里叶变换 算法,
可以将两位n-bit的大整数乘法在O(n lg n)计算出来。


FFT简介:快速傅里叶变换, 参考 http://beige.ucs.indiana.edu/B673/node12.html


n = 8 为例子, 计算两个4位数的乘法。
寻找根w使得 w^n = 1.
A[0..7][0..7]: A[i][j] = w^{i*j}, 其中 w^n = 1.
A^{-1} = w^{-1} ^ {i*j}.


对于大整数X和Y,首先做矩阵乘法运算
X' = A*X
Y' = A*Y
然后对X' Y' 对应bit位 对应相乘
Z = X' .* Y' (对应相乘)
最后还原
Z' = A^{-1}*Z


快速傅里叶变换的高效之处在于,A矩阵是具有很强的结构性,因此矩阵乘法运算过程可以优化到O(n lg n).


关于如何选择根w.
采用数论中的 root https://en.wikipedia.org/wiki/Root_of_unity_modulo_n
避免浮点数运算。 


对于n=2^k, 寻找大素数MOD,使得 存在 w, w^{2^k}=1 (mod MOD).

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<ctime>
#include<cmath>

#define EXC(a,b) a ^ b ? a ^= b ^= a ^= b : 0
#define EXCB(a,b) a > b ? a ^= b ^= a ^= b : 0
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define FORE(i,a,b) for(int i=(a);i<=(b);i++)
#define FORI(TYPE,it,s) for(TYPE::iterator it=s.begin();it!=s.end();it++) 
#define MST(a,b) memset(a,b,sizeof(a))
#define SCF(a) scan
在Python中,梅森素数是指形如\(2^p - 1\)且为素数的数字,其中p也是质数。而完美数是指正整数等于其所有真因数(除了自身以外的因数)之和的数。例如6是完美数,因为它的因数有1、2、3,它们相加等于6。 然而,判断一个数是否为完美数需要先找出这个数的所有因数,然后验证它们的和是否等于该数本身。对于梅森素数,我们首先检查\(2^p - 1\)是否为素数,如果它是素数,我们就需要进一步确认其是否为完美数。这通常涉及到复杂的计算,尤其是当N较大时。 以下是简单的步骤: 1. 定义一个函数`is_perfect_number(n)`来检查n是否为完美数。 2. 定义一个辅助函数`is_prime(p)`用于检查p是否为素数。 3. 循环遍历p(从2开始),计算\(2^p - 1\)并检查是否为素数,如果是,则进一步检查它是否为完美数。 以下是一个简化的代码示例: ```python def is_prime(num): if num < 2: return False for i in range(2, int(num**0.5) + 1): if num % i == 0: return False return True def mersenne_perfect_numbers(N): perfect_numbers = [] for p in range(2, N): # 从2到N-1,因为N本身不会是Mersenne数 mp = 2**p - 1 if is_prime(mp): factors_sum = sum(i for i in range(1, mp//2+1) if mp % i == 0) if factors_sum == mp: perfect_numbers.append(mp) return perfect_numbers # 使用函数并打印结果 N = 1000 # 可以调整此值以寻找更大数据范围内的完美数 perfects_below_N = mersenne_perfect_numbers(N) print(f"小于{N}的梅森素数完美数: {perfects_below_N}") ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值