数论基础算法总结(python版)

本文总结了数论中常用的算法,包括快速幂、Fermat素性检验、Solovay-Stassen检验、Miller-Rabin检验及中国剩余定理等,并提供了Python实现代码。

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

/*
    Author: wsnpyo
    Update Date: 2014-11-16
Algorithm: 快速幂/Fermat, Solovay_Stassen, Miller-Rabin素性检验/Exgcd非递归版/中国剩余定理 */ import random def QuickPower(a, n, p): # 快速幂算法 tmp = a ret = 1 while(n > 0): if (n&1): ret = (ret * tmp) % p tmp = (tmp * tmp) % p n>>=1 return ret def Jacobi(n, m): # calc Jacobi(n/m) n = n%m if n == 0: return 0 Jacobi2 = 1 if not (n&1): # 若有n为偶数, 计算Jacobi2 = Jacobi(2/m)^(s) 其中n = 2^s*t t为奇数 k = (-1)**(((m**2-1)//8)&1) while not (n&1): Jacobi2 *= k n >>= 1 if n == 1: return Jacobi2 return Jacobi2 * (-1)**(((m-1)//2*(n-1)//2)&1) * Jacobi(m%n, n) def Exgcd(r0, r1): # calc ax+by = gcd(a, b) return x x0, y0 = 1, 0 x1, y1 = 0, 1 x, y = r0, r1 r = r0 % r1 q = r0 // r1 while r: x, y = x0 - q * x1, y0 - q * y1 x0, y0 = x1, y1 x1, y1 = x, y r0 = r1 r1 = r r = r0 % r1 q = r0 // r1 return x def Fermat(x, T): # Fermat素性判定 if x < 2: return False if x <= 3: return True if x%2 == 0 or x%3 == 0: return False for i in range(T): ran = random.randint(2, x-2) # 随机取[2, x-2]的一个整数 if QuickPower(ran, x-1, x) != 1: return False return True def Solovay_Stassen(x, T): # Solovay_Stassen素性判定 if x < 2: return False if x <= 3: return True if x%2 == 0 or x%3 == 0: return False for i in range(T): # 随机选择T个整数 ran = random.randint(2, x-2) r = QuickPower(ran, (x-1)//2, x) if r != 1 and r != x-1: return False if r == x-1: r = -1 if r != Jacobi(ran, x): return False return True def MillerRabin(x, ran): # x-1 = 2^s*t tx = x-1 s2 = tx&(~tx+1) # 取出最后一位以1开头的二进制 即2^s r = QuickPower(ran, tx//s2, x) if r == 1 or r == tx: return True while s2>1: # 从2^s -> 2^1 循环s次 r = (r*r)%x if r == 1: return False if r == tx: return True s2 >>= 1 return False def MillerRabin_init(x, T): #Miller-Rabin素性判定 if x < 2: return False if x <= 3: return True if x%2 == 0 or x%3 == 0: return False for i in range(T): # 随机选择T个整数 ran = random.randint(2, x-2) if not MillerRabin(x, ran): return False return True def CRT(b, m, n): # calc x = b[] % m[] M = 1 for i in range(n): M *= m[i] ans = 0 for i in range(n): ans += b[i] * M // m[i] * Exgcd(M//m[i], m[i]) return ans%M

 

以上作为半个学期来数论学习的一个小结,也许以后难以再系统的学习数论了。略伤感咿

  —— 多谢信息安全数学基础的老师

 

转载于:https://www.cnblogs.com/Mathics/p/4101467.html

### 数论算法概述 数论是数学的一个重要分支,专注于研究整数及其性质。在计算机科学领域,数论的应用十分广泛,尤其是在密码学、数据加密、优化问题和算法设计等领域。以下是关于数论算法的一些核心知识点及相关实现方法。 --- #### 1. **质数判定** 质数是指仅能被 `1` 和其本身整除的大于 `1` 的自然数。常见的质数判定方法有: - **朴素算法**: 遍历从 `2` 到 `sqrt(n)` 的所有整数来判断是否存在因子[^1]。 ```java public static boolean isPrime(int n) { if (n <= 1) return false; for (int i = 2; i * i <= n; i++) { // 只需遍历到 sqrt(n) if (n % i == 0) return false; } return true; } ``` - **埃拉托斯特尼筛法**: 提前筛选出一定范围内的所有质数,适用于批量查询场景。 ```cpp void sieveOfEratosthenes(int maxN, vector<bool>& primes) { primes.assign(maxN + 1, true); primes[0] = primes[1] = false; for (int p = 2; p * p <= maxN; ++p) { if (primes[p]) { for (int multiple = p * p; multiple <= maxN; multiple += p) { primes[multiple] = false; } } } } ``` --- #### 2. **最大公约数(GCD)** GCD 是指两个或多个整数共有的约数中最大的一个。常用的 GCD 计算方法为欧几里得算法。 ```python def gcd(a, b): while b != 0: a, b = b, a % b return a ``` 该算法基于如下原理:两数的最大公约数等于较小数与两者相除余数的最大公约数。 --- #### 3. **扩展欧几里得算法** 扩展欧几里得算法不仅能够求解两数的 GCD,还能找到满足 \( ax + by = \text{gcd}(a,b) \) 的整数解 \( x,y \)。 ```cpp pair<int, pair<int, int>> extendedEuclid(int a, int b) { if (b == 0) return make_pair(a, make_pair(1, 0)); auto result = extendedEuclid(b, a % b); int g = result.first; int y = result.second.second; int x = result.second.first - (a / b) * y; return make_pair(g, make_pair(x, y)); } ``` 此算法可用于解决线性同余方程等问题。 --- #### 4. **快速幂算法** 快速幂是一种用于高效计算大指数次幂的方法,尤其适合涉及模运算的情况[^5]。 ```cpp const int MOD = 1e9 + 7; long long fastPower(long long base, long long exp) { long long result = 1; while (exp > 0) { if (exp & 1) result = (result * base) % MOD; base = (base * base) % MOD; exp >>= 1; } return result; } ``` 上述代码利用了二分的思想,在对数时间内完成幂运算。 --- #### 5. **中国剩余定理(CRT)** CRT 主要用于解决一组模线性同余方程组的问题[^2]。假设存在若干形如 \( x \equiv r_i \ (\text{mod} \ m_i) \) 的约束条件,则 CRT 给出了唯一解的存在性和构造方式。 具体实现较为复杂,通常需要借助扩展欧几里得算法逐步合并模数。 --- #### 6. **其他常用概念** - **欧拉函数 φ(n)**: 表示小于等于 \( n \) 且与 \( n \) 互素的正整数个数[^3]。 ```cpp int eulerPhi(int n) { int result = n; for (int p = 2; p * p <= n; ++p) { if (n % p == 0) { while (n % p == 0) n /= p; result -= result / p; } } if (n > 1) result -= result / n; return result; } ``` - **费马小定理**: 若 \( p \) 为质数且 \( a \not\equiv 0 \ (\text{mod}\ p) \),则 \( a^{p-1} \equiv 1 \ (\text{mod}\ p) \)[^4]。 --- ### 总结 以上介绍了多种经典的数论算法及其应用场景,涵盖了从基础理论到实际编码实践的内容。每种算法都有其特定用途,合理选择可以显著提升程序性能。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值