首页 > 其他分享 >EXGCD 和 EXCRT

EXGCD 和 EXCRT

时间:2024-11-05 21:43:41浏览次数:1  
标签:gcd text LL EXGCD EXCRT 整数 ax equiv

EXGCD 和 EXCRT

前言

我与这两个算法有很深的渊源。

第一次遇到是三年前的五校联考,\(\text{t1}\) 需要用到,于是我成了全场唯一一个没切 \(\text{t1}\) 的。

第二次是两年前湖南省集,我依稀记得这是第二场的 \(\text{Day1 T2}\),我花了 \(\text{2.5h}\) 去推 \(\text{exCRT}\) 的式子,加上那题要用 \(\text{SA/SAM}\) 之类的字符串技巧,写出来差不多有 \(\text{7k}\),尽管我拼尽全力,但最终还是挂成了 \(28\)。导致即使切了 \(\text{Day2 T1}\) 的神秘构造,还是没有翻盘。

第三次是一年前的正睿,这题推的比较快,只写了 \(\text{1h}\) 就过了大样例。但因为没总结过 \(\text{exCRT}\) 的板子,于是喜提没开 \(\text{int128}\)。\(100 \rightarrow 50\)。

三年过去,我终于学会了 \(\text{exCRT}\)。我成功了,我不再是从前的那个自我了。

以下均是我自己推的,所以仅供参考。

正文

假设我们要求不定方程 \(ax + by = c\) 的一组整数解(为方便起见默认 \(a, b, c > 0\),其余情况也是类似的)。

显然并不是所有这样的方程都有整数解。比如 \(2x + 4y = 1\) 显然无整数解。

我们试着给出一个方程有整数解的充要条件:\(\gcd(a, b) \mid c\)。下面令 \(g = \gcd(a, b), l = \text{lcm}(a, b)\)。必要性较为显然,因为 \(x, y\) 均为整数,且 \(g \mid a, g \mid b\),所以 \(g \mid ax + by = c\)。

充分性我们后面用 \(\text{exGCD}\) 构造即可。现在考虑我们只需求一组 \(ax + by = g\) 的整数解,求完后只需 \(x \gets x \times \frac{c}{g}, y \gets y \times \frac{c}{g}\) 即可得到原方程的解。

对于求解 \(ax + by = g\) 的问题,我们考虑递归下去求解 \(by + (a \bmod b) = g\),由于 \(\gcd\) 的性质:\(\gcd(a, b) = \gcd(b, a \bmod b)\),所以产生出的子问题和原来形式一样。

这样递归下去显然有边界情况,也就是递归求 \(\gcd\) 的边界:\(b = 0\)。此时方程退化为 \(ax + 0y = g\),因为 \(\gcd\) 运算有 \(\gcd(a, 0) = a\) 的规定,所以 \(a = g\),方程其实是 \(ax + 0y = a\)。我们令 \(x = 1, y = 0\) 即可。

于是考虑如何通过子问题导出原问题的解。假设在子问题种我们得到一组解 \(x_0, y_0\),代入得 \(by_0 + (a \bmod b)x_0 = g \Leftrightarrow by_0 + ax_0 - \lfloor \frac{a}{b} \rfloor bx_0 = g \Leftrightarrow b(y_0 - \lfloor \frac{a}{b} \rfloor x_0) + ax_0 = g\)。则可以自然的想到令 \(y = y_0 - \lfloor \frac{a}{b} \rfloor x_0, x = x_0\) 即可。

于是我们成功的求出 \(ax + by = c\) 的一组整数解。一个性质是若 \(b \neq 0\),这样求出的解满足 \(|x| \le |b|, |y| \le |a|\)(这里允许了参数 \(a, b\) 为负数)。证明可以简单归纳,这里就不展开了。

显然 \(ax + by = c\) 有无数组整数解,在得到一组解后,我们可以通过形如 \(x \gets x + \delta b, y \gets y - \delta a\) 的调整得到所有整数解。

代码实现如下:

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 -= (a / b) * x;
}

\(\text{exGCD}\) 在 \(\text{OI}\) 中有一个经典应用是求逆元。假设要求 \(a\) 在 \(\bmod p\) 意义下的逆元 \(b\),即求一个 \(b\) 满足 \(ab \equiv 1 \pmod p\)。由逆元的性质可知只有 \(a \perp p\) 时 \(a\) 才有逆元。

做法是设 \(ab = kp + 1\),移项成 \(\text{exGCD}\) 的形式就是 \(ab - kp = 1\),解出一组 \(b, k\) 即可。容易发现保证存在逆元的限制 \(a \perp b\) 恰好对应的 \(\text{exGCD}\) 的要求:\(\gcd(a, p) \mid 1\),即 \(\gcd(a, p) = 1 \Leftrightarrow a \perp p\)。

接下来进入 \(\text{exCRT}\) 的部分。大家应该听过韩信点兵的故事,形式化的说就是求

\[\begin{cases} x \equiv b_1 \pmod{a_1} \\ x \equiv b_2 \pmod{a_2} \\ \dots\\ x \equiv b_n \pmod{a_n} \end{cases} \]

的一个整数解 \(x\)。

首先显然限制可以两两合并,如果我们能够合并两个方程,那么最后一路合并下来就好了。

于是我们考虑如何通过两个限制 \(x \equiv a \pmod b\) 和 \(x \equiv c \pmod d\) 合并成一个新的限制。

将限制分别写成 \(x = k_1a + b\),\(x = k_2c + d\),其中 \(k_1, k_2\) 均为整数的形式。合并一下就是 \(k_1a + b = k_2c + d\)。

移一下项容易得到 \(k_1a + k_2(-c) = d - b\),于是可以令 \(g = \gcd(a, c), l = \text{lcm}(a, c)\),有解当且仅当 \(g \mid d - b\)。

此时可以 \(\text{exGCD}\) 求出 \(k_1a + k_2(-c) = g\) 的一组解 \(k_1, k_2\) 于是可以得到 \(x \equiv k_1a\frac{d - b}{g} + b \pmod l\),这里之所以是 \(\bmod l\) 可以参考前面讲的通过调整得出所有整数解的方法。

模板大概是这样的:

LL Exgcd (LL a, LL b, LL &x, LL &y) {
  if (!b) return x = (a > 0 ? 1 : -1), y = 0, abs(a);
  LL ret = Exgcd(b, a % b, y, x);
  return y -= (a / b) * x, ret;
}

void Excrt (LL &a, LL &b, LL c, LL d) {
  LL x, y, g = Exgcd(a, -c, x, y), l = a / g * c;
  LL r = ((i128(a) * x * ((d - b) / g) + b) % l + l) % l;
  a = l, b = r; 
}

标签:gcd,text,LL,EXGCD,EXCRT,整数,ax,equiv
From: https://www.cnblogs.com/estruct/p/18528933

相关文章

  • 二元一次不定方程(Exgcd)(更方便的解法)
    扩展欧几里得算法(Exgcd)裴蜀定理对于任意一组整数\(a,b\),存在一组整数\(x,y\),满足\(ax+by=\gcd(a,b)\)。Proof:考虑数学归纳法。当\(b=0\)时,由于\(\gcd(a,0)=a\),则对于\(ax+0y=a\)这个不定方程,\(x=1\),\(y\)取任意整数。假设存在一组整数\(x,y\),满足$bx+(a\bmodb)y......
  • Exgcd学习笔记
    Exgcd学习笔记引理Bézout'stheorem对于\(gcd(a,b)=d\)的情况,一定\(\existsx,y\),使得\(ax+by=d\)成立。相反的,当解方程\(ax+by=c\)时,若\(c\)不是\(d\)的倍数,那么此方程一定无解。Exgcd推导我们知道如何通过辗转相除法求出\(gcd(a,b)\),那么结合贝祖定理,不难......
  • Exgcd 和 Excrt 的一些推导
    Exgcd和Excrt的一些推导ExgcdExgcd是用来求解二元一次不定方程的算法,即\[ax+by=c\]根据贝祖定理,该方程有解当且仅当\(\gcd(a,b)\midc\),所以只用求解\[ax+by=\gcd(a,b)\]又因为\[\gcd(a,b)=\gcd(b,a\bmodb)\]可以先求解\[bx'+(a\bmodb)y'=\gcd(a,b)\]变形得\[......
  • 基础数论 欧拉定理与exgcd
    欧拉定理:若正整数\(a,n\)互质,则\(a^{\varphi(p)}\equiv1(\bmodp)\)推论(扩展欧拉定理):\[a^b\equiv\begin{cases}a^{b\\bmod\\varphi(p)}\\\\\\\\\\gcd(a,p)=1\\a^b\\\\\\\\\\\\\\\\\\\\\\gcd(a,p)!......
  • 二元一次不定方程(Exgcd)(更方便的解法)
    扩展欧几里得算法(Exgcd)裴蜀定理对于任意一组整数\(a,b\),存在一组整数\(x,y\),满足\(ax+by=\gcd(a,b)\)。Proof:考虑数学归纳法。当\(b=0\)时,由于\(\gcd(a,0)=a\),则对于\(ax+0y=a\)这个不定方程,\(x=1\),\(y\)取任意整数。假设存在一组整数\(x,y\),满足$bx+(a\bmodb)y......
  • 推式子——拓展欧几里德算法exgcd
    试求方程\(ax+by=\gcd(a,b)\)的一组整数解,其中\(a\)和\(b\)是给定的数提前准备好一个式子:辗转相除法\[\gcd(a,b)=\gcd(b,a\bmodb)\]同时我们可以注意到,\(\bmod\)的等价版本:\[a\bmodb=a-b\lfloor\frac{a}{b}\rfloor\]开始推式子首先考虑\(b=0\)的情况,因为......
  • exgcd
    裴蜀定理对于任意整数\(a,b\)都存在整数\(x,y\),使得\(ax+by=gcd(a,b)\)扩展欧几里得算法(exgcd)设整数\(a,b,x,y\)满足\(ax+by=gcd(a,b)\)若\(b=0\),则\(x=1\),\(y\)取任意整数若\(b>0\)\[ax+by=gcd(a,b)\]\[=gcd(b,a\mod\b)\]\[=bx_0+(a\mod\b)y_0\]\[=bx_0+(a-......
  • 扩展欧几里得算法(exGcd)
    扩展欧几里得算法(ExtendedEuclideanalgorithm,EXGCD),常用于求\(ax+by=c\)的一组可行解。过程设\(ax_1+by_1=\gcd(a,b)\)\(bx_2+(a\modb)y_2=gcd(b,a\modb)\)由欧几里得算法:\(\gcd(a,b)=gcd(b,a\modb)\)所以:\(ax_1+by_1=bx_2+(a\modb)y_2\)又因为:\(a\mod......
  • exgcd 通解(新)
    可能不全,老文章在这什么是通解,我们知道二元一次方程,是如果只有一个式子,那么解会有无数个,而通解就是指让我们只找到一个解就可以推出其他所有解的式子。注意以下变量都为整数。知道了定义下面就是推式子了,首先设\(x,y\)是\(ax+by=\gcd(a,b)\)的一个解,那么有\[y=\le......
  • [题解]P5656 【模板】二元一次不定方程 (exgcd)
    P5656【模板】二元一次不定方程(exgcd)若存在\(ax+by=c\),则可以根据特解\(x,y\)求出任意通解\(x',y'\):\(\begin{cases}x'=x+k*\frac{b}{\gcd(a,b)}\\y'=y-k*\frac{a}{\gcd(a,b)}\end{cases}(k\in\mathbb{Z})\)求特解的方法是「扩展欧几里得(exgcd)」,如果没接触过可以先阅读......