首页 > 编程语言 >基础数论算法汇总

基础数论算法汇总

时间:2024-11-08 16:19:58浏览次数:1  
标签:gcd 数论 dfrac bmod 汇总 varphi 算法 逆元 ax

乘法逆元

给定 \(n\) 个正整数 \(a_i\),求它们在模 \(p\) 意义下的乘法逆元。

逆元是模意义下的倒数,能够将模意义下无法直接计算的除法转化为乘法。先来总结一下常用的求单个逆元的方法:

扩展欧几里得

\(O(\log n)\) 地求一个数的逆元,要求 \(a,p\) 互质即可(\(p\) 为模数),原理为解线性同余方程 \(ax\equiv 1(\bmod p)\)。

void exgcd(int a, int b, int& x, int& y) {
    if (b == 0) return x = 1, y = 0, void();
    exgcd(b, a % b, y, x);
    y = y - a / b * x;
}
exgcd(a, p, inv, temp);

快速幂

根据费马小定理,当 \(p\) 为质数时,\(a\) 在模 \(p\) 意义下的逆元是 \(a^{p-2}\),可直接用快速幂 \(O(\log n)\) 求解。注意: 扩展欧几里得的条件是 \(a,p\) 互质即可,但快速幂法要求 \(p\) 必须是质数!

下面两种方法用于求多个数的逆元:

线性求逆元

显然 \(1^{-1}\equiv 1(\bmod p)\),我们从 \(1\) 开始向后迭代求逆元。设 \(k=\lfloor\dfrac{p}{i}\rfloor,j=p\bmod i\),有 \(p=ki+j\)。所以 \(ki+j\equiv 0(\bmod p)\)。两边同乘 \(i^{-1},j^{-1}\),得到 \(kj^{-1}+i^{-1}\equiv 0(\bmod p)\),所以要求的 \(i^{-1}=-kj^{-1}\)。因为 \(j=p\bmod i<i\),而在迭代到 \(i\) 时,\([1,i)\) 的逆元都已经求出,则可以直接根据 \(j^{-1}\) 推出 \(i^{-1}\) 的值。

代码实现比较简单:

inv[1] = 1
for i in range(2, n + 1):
    k = p // i
    j = p % i
    inv[i] = (p - k) * inv[j] % p # p-k 避免出现负数

线性求任意数逆元

当要求逆元的数不连续时(如本题中的情况),可以通过前缀积处理。

//求前缀积 s[i]
s[0] = 1;
for (int i = 1; i <= n; i++) s[i] = (long long)s[i - 1] * i % p;
// 费马小定理求 n 个数积的逆元(也就是逆元的积)
sv[n] = qpow(s[n], p - 2, p);
// 逐个消去 a[i] 的逆元,得到逆元前缀积
for (int i = n; i > 1; i--) sv[i - 1] = (long long)sv[i] * a[i] % p;
// 对于每个逆元前缀积,消去 a[1...i-1] 的逆元积,得到 a[i] 的逆元
for(int i = 1; i <= n; i++) inv[i] = (long long)sv[i] * s[i - 1] % p;

这个题也可以直接通分:设 \(x = \prod a_i\),原式 \(\sum\limits_{i=1}^{n}\dfrac{k^i}{a_i}(\bmod p)=\dfrac{\sum\limits_{i=1}^{n}k^i \dfrac{x}{a_i}}{x}\),其中 \(\dfrac{x}{a_i}\) 可以通过预处理前后缀积求出,求一次 \(x\) 的逆元即可。

裴蜀定理

\(a,b\) 为不全为 \(0\) 的整数,\(ax+by=c\) 有整数解当且仅当 \(\text{gcd}(a,b)|c\)。证明如下:设 \(d=\text{gcd}(a,b)\),显然 \(d|a,d|b\),取 \(x,y\in \text{Z}\),有 \(d|ax,d|by\),所以 \(d|(ax+by)\),得证。容易推广到多个整数的情况。

此题中,由裴蜀定理的推广得,\(\text{gcd}(A_1,A_2\cdots A_n)|S\),取 \(S\) 为最小公约数即可。

def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a % b)

n = int(input())
a = list(map(abs, map(int, input().split())))
result = a[0]

for i in range(1, len(a)):
    result = gcd(result, a[i])

print(result)

扩展欧几里得

【模板】同余方程

求关于 \(x\) 的同余方程 \(ax\equiv 1 (\bmod b)\) 的最小正整数解。根据取模的性质,这个方程相当于 \(ax+by=1\),其中 \(y\) 为负数,形式类似于扩展欧几里得的经典形式 \(ax+by=\gcd(a,b)\)。

方程 \(ax+by=m\) 有整数解的必要条件是 \(\gcd(a,b)|m\),此处 \(m=1\),所以有 \(\gcd(a,b)=1=m\)。也就是说方程 \(ax+by=1 \iff ax+by=\gcd(a,b)\),我们可以直接使用扩展欧几里得求解。

假设我们已知一组整数 \(x_1,y_1\) 使得 \(bx_1+(a\bmod b)y_1=\gcd(a,b)\) 成立,则有 \(ax+by=bx_1+(a\bmod b)y_1\) 成立。由取模的性质得,\(ax+by=bx_1+(a-b\cdot\lfloor\dfrac{a}{b}\rfloor)y_1=ay_1+b(x_1+\lfloor\dfrac{a}{b}\rfloor y_1)\),得到一组解 \(x=y_1,y=x_1+\lfloor\dfrac{a}{b}\rfloor y_1\)。这样,只要知道了一组 \(x_1,y_1\),就能够得到一组 \(x,y\)。

那么怎么求 \(x_1,y_1\) 呢?我们发现,定义 \(x_1,y_1\) 的方程 \(bx_1+(a\bmod b)y_1=\gcd(a,b)\) 和 \(ax+by=\gcd(a,b)\) 形式相同,可以用同样的方法,令 \(ax+by=\gcd(a,b)\) 中的 \(a=b,b=a\bmod b\),再去找一组 \(x_2,y_2\) 满足 \(bx_2+(a\bmod b)y_2=\gcd(a,b)\)。知道了 \(x_2,y_2\),就知道了 \(x_1,y_1\)……依此类推。

类似欧几里得算法,递归边界是 \(a=\gcd(a,b),b=0\),又 \(ax_n+by_n=\gcd(a,b)\),所以 \(x_n=1,y_n\) 取任意值(为避免溢出,一般取 \(0\)),递归回去求出一开始的 \(x,y\) 即可。

此时的答案尚不符合题目“最小”的要求,需要进一步处理。设 \(a=m+bn\),\(n\) 极大,于是原方程为 \((m+bn)x+by=1 \iff mx+b(nx+y)=1\) 使得 \(x\) 最小,所以直接 \(x\bmod b\)即可,注意调整范围避免出现负数。

void exgcd(int a, int b, int &x, int &y) {
    if (!b) return x = 1, y = 0, void();
    exgcd(b, a % b, y, x);
    y = y - (a / b) * x;
}
exgcd(a, b, x, y);
x = (x % b + b) % b; // 调整答案范围

【模板】二元一次不定方程:没有整数解当且仅当 \(\gcd(a,b)\nmid c\),直接输出 -1

用 exgcd 解方程 \(ax+by=\gcd(a,b)\) 得到一组特解 \(x_0,y_0\)。对原方程变形得到 \(a\cdot\dfrac{xc}{\gcd(a,b)}+b\cdot\dfrac{yc}{\gcd(a,b)}=c\),于是有 \(ax+by=c\) 的一组特解 \(x_1=\dfrac{xc}{\gcd(a,b)},y_1=\dfrac{yc}{\gcd(a,b)}\)。

接下来,由「同余方程」一题中的技巧,用 x=(x%b+b)%b, y=(y%a+a)%a; 求出 \(x,y\) 的最小取值 \(x_{\min},y_{\min}\),因为 \(x\) 增大 \(y\) 减小,可以直接分别带入原方程,求出 \(y_{\max},x_{\max}\)。如果 \(x_{\max},y_{\max}<0\),则没有正整数解,直接输出两个最小值即可;否则有正整数解,分别输出最大值、最小值和解的个数。

扩展欧拉定理

求 \(a^b \bmod m, b\le 10^{200000}\)。

首先引入三种可以通过取模缩小幂指数的方法。

  1. 费马小定理:当 \(a,p\in \mathbb{Z},\space p\) 为质数且 \(p\nmid a\) 时,\(a^{p-1}\equiv 1(\bmod\space p)\),所以有 \(a^b\equiv a^{b\bmod (p-1)}(\bmod\space p)\);
  2. 欧拉定理:当 \(a,m\in\mathbb{Z},\space a,m\) 互质时,\(a^{\varphi(m)}\equiv 1(\bmod\space m)\),其中欧拉函数 \(\varphi(n)\) 为 \([1,n]\) 中与 \(n\) 互质的数的个数。由此, \(a^b=a^{b\bmod\varphi(m)}(\bmod\space m)\);
  3. 扩展欧拉定理:当 \(a,m\in\mathbb{Z}\) 时,
    \( a^b=\left\{ \begin{aligned} & a^b&, b\le\varphi(m) \\\ & a^{b\bmod\varphi(m)+\varphi(m)},&b>\varphi(m) \end{aligned} \right.(\bmod\space m) \)。

此题没有给出 \(a,m\) 间的互质关系,只能采用扩展欧拉定理解决。只需求出 \(\varphi(m)\) 即可,我们可以采取分解质因数的方法,结合欧拉函数公式
\( \varphi(n)=\left\{ \begin{aligned} & 1 &,n=1 \\\ & n\prod\limits_{i=1}^{k}(1-\dfrac{1}{p_i}) &,n\neq 1 \end{aligned} \right. \)
来 \(O(\sqrt{m})\) 地求解。公式里的 \(k,p_i\) 来自 \(n\) 的唯一分解 \(n=\prod\limits_{i=1}^{k} p_i,\space p_i\) 为质数。

int phi = m;
for (int p = 2; n > 0; p++) {
    if (n % p != 0) continue;
    phi -= phi / p; // 公式中 (1-1/p) 的变形
    while (n % p == 0) n /= p;
}

下面延伸介绍一下欧拉函数的知识。除了公式,还有五种方法可以计算欧拉函数:

  1. 若 \(p\) 为质数,\(\varphi(p)=p-1\);
  2. 若 \(p\) 为质数,\(n=p^k\),有 \(\varphi(n)=p^k-p^{k-1}\),即 \([1,n]\) 去掉了 \(p,2p,3p\cdots p^{k-1}p\) 共计 \(p^{k-1}\) 个数;
  3. 积性:若 \(a,b\) 互质,\(\varphi(ab)=\varphi(a)\varphi(b)\),因为此时 \(a,b\) 的质因子 \(\{pi\},\{qi\}\) 均不相同,所以 \(\varphi(ab)=ab\prod\limits_{i=1}^{k}(1-\dfrac{1}{p_i})\prod\limits_{j=1}^{l}(1-\dfrac{1}{q_i})=a\prod\limits_{i=1}^{k}(1-\dfrac{1}{p_i})\times b\prod\limits_{j=1}^{l}(1-\dfrac{1}{q_i})=\varphi(a)\varphi(b)\);
  4. 不完全积性:若 \(p\) 为质数,\(n\) 为 \(p\) 的倍数,则 \(n\) 与 \(np\) 的质因数种类上完全相同,有 \(\varphi(np)=np\prod\limits_{i=1}^{k}(1-\dfrac{1}{p_i})=n\prod\limits_{i=1}^{k}(1-\dfrac{1}{p_i})\times p=\varphi(n)\times p\);
  5. 若 \(n\) 为奇数,则 \(\varphi(2n)=\varphi(n)\),由方法 1,3 可推得。

结合方法 1,3,4,我们可以用线性筛的方法 \(O(n)\) 的计算 \(\varphi(i)\),实现如下:

for (int i = 2; i <= n; i++) {
    if (!isNotPrime[i]) {
        primes.push_back(i);
        phi[i] = i - 1; // 方法 1
    }
    for (int j = 0; j < primes.size() && i * primes[j] > n; j++) {
        isNotPrime[i * primes[j]] = true;
        if (i % primes[j] == 0) {
            phi[i * primes[j]] = phi[i] * primes[j]; // 方法 4
            break; // 线性筛原理:只让合数被「最小」质因数筛掉
        }
        phi[i * primes[j]] = phi[i] * phi[primes[j]]; // 方法 3
    }
}

标签:gcd,数论,dfrac,bmod,汇总,varphi,算法,逆元,ax
From: https://www.cnblogs.com/th19/p/18535329

相关文章

  • 利用dem和DOM生成路线算法的实现
    要在C++中实现一个基于DEM(数字高程模型)和DOM(数字正射影像)的路线生成算法,满足以下要求:规避DEM中的地物:利用DEM的高度数据识别障碍物,如山体、水域等不可通行区域,并设计路径绕过它们。判断DOM中的地物:结合DOM数据对地物进行分类和识别,如道路、建筑、植被等。生成连续的线路......
  • 改进的蜣螂算法(IDBO)优化长短期记忆神经网络原理及MATLAB代码复现
    目录0引言1数学模型2模型性能可视化3MATLAB代码3.1伪代码程序图3.2IDBO-LSTM0引言针对DBO全局探索能力不足、易陷入局部最优以及收敛精度不理想等问题,有学者提出了一种混合多策略改进的蜣螂优化算法(IDBO)。该算法采用混沌映射结合随机反向学习策略初始化种群提......
  • 改进的蜣螂算法(IDBO)优化支持向量机原理及MATLAB代码复现
    目录0引言1数学模型2模型性能可视化3MATLAB代码3.1伪代码程序图3.2IDBO-SVR、IDBO-SVM0引言针对DBO全局探索能力不足、易陷入局部最优以及收敛精度不理想等问题,有学者提出了一种混合多策略改进的蜣螂优化算法(IDBO)。该算法采用混沌映射结合随机反向学习策略初始......
  • 改进的蜣螂算法(IDBO)优化BP神经网络原理及MATLAB代码复现
    目录0引言1数学模型2模型性能可视化3MATLAB代码3.1伪代码程序图3.2IDBO-BP0引言针对DBO全局探索能力不足、易陷入局部最优以及收敛精度不理想等问题,有学者提出了一种混合多策略改进的蜣螂优化算法(IDBO)。该算法采用混沌映射结合随机反向学习策略初始化种群提高......
  • 算法定制LiteAIServer烟火识别软件烟火检测算法有哪些优势呢?
    在现代社会,随着人工智能技术的飞速发展,各种智能监控系统在公共安全、工业生产、环境保护等领域得到了广泛应用。其中,烟火检测作为预防火灾的重要手段,其准确性和实时性对于减少火灾损失、保障人民生命财产安全具有重要意义。摄像机实时接入分析平台LiteAIServer作为一款基于人工......
  • 在复杂环境中,算法定制LiteAIServer视频智能分析平台如何提高对比度识别的准确率?
    随着科技的飞速发展,视频监控已经成为各行各业不可或缺的一部分。然而,视频质量的好坏直接影响到监控效果,其中对比度作为衡量图像质量的重要指标之一,对于视频内容的清晰度和细节表现至关重要。为了提高对比度误报识别的准确率,算法定制LiteAIServer视频智能分析平台凭借其先进的图......
  • 摄像机视频分析软件下载LiteAIServer入侵检测算法平台部署智能化安防
    在当今社会,安全问题已成为各行各业不可忽视的重要议题。特别是在需要高度监控的场合,如工厂、仓库、城市重要区域等,有效防范未经授权的行人入侵成为了亟待解决的问题。视频智能分析平台部署LiteAIServer行人入侵检测算法应运而生,以其卓越的技术实力和广泛的应用价值,为这一领域带......
  • CPU算法分析LiteAIServer视频智能分析平台视频智能分析:抖动、过亮与过暗检测技术
    随着科技的飞速发展,视频监控系统在各个领域的应用日益广泛。然而,视频质量的好坏直接影响到监控系统的效能,尤其是在复杂多变的光照条件下和高速数据传输中,视频画面常常出现抖动、过亮或过暗等问题,导致监控视频难以提供有效的信息。为了解决这些挑战,视频智能分析平台LiteAIServer......
  • 视频智能分析网关视频分析网关区域人数统计检测算法探析
    随着城市化进程的加快和公共安全管理需求的提升,对公共场所、工业区域等人流量密集场所的监控和管理变得尤为重要。传统的视频监控系统已经无法满足现代智能化管理的需求,市场迫切需要一种能够实现实时监控、智能分析和自动报警的高效解决方案。基于此,区域人数统计视频分析网关应运......
  • 无处不在的算法,竟然帮你找到理想对象!
    内容概要在当今这个快速发展的信息时代,恋爱与婚姻的挑战也随之变化。无论是在繁忙的城市还是宁静的小镇,现代人都面临着寻找合适伴侣的困惑。传统的约会方式渐渐被新颖的技术手段取代,算法的崛起无疑为这一过程带来了机遇。通过数据分析和智能匹配,*我们能够在浩瀚的人海中发现......