基本数论算法
以下讨论的数都为整数
欧几里得算法
\(gcd(a,b)\) 为 \(a,b\) 的最大公因数,有 \(gcd(a,b) = gcd(b,a\bmod b)\) 。
我们设 \(d=gcd(a,b)\) , \(a=k \times b +r(0≤r<b)\) ,那么一定有 \(d\mid b\) , \(d\mid (a-k\times b)\)
\(a<b\rightarrow gcd(a,b) = gcd(b,a)\)
\(a≥b\rightarrow gcd(a,b) = gcd(b,a\mod b)\) 其中 \(r<b<b+r<\frac{a}{2}\)
复杂度是 \(log\) 级别的,若干次迭代后 \(a,b\) 逐渐接近 \(1\) ,当 \(a\bmod b=0,b\) 即为最大公约数
点击查看代码
LL gcd(LL a,LL b){
LL r=a%b;
while(r)a=b,b=r,r=a%b;
return b;
}
扩展欧几里得
可以用来求解二元不定方程 \(ax+by = c\) 的不定方程,显然若 \(gcd(a,b)\nmid c\) 方程无解,它是欧几里得算法的扩展:我们试图求解 \(ax+by=gcd(a,b)\) ,然后通过等式同乘 \(\frac{c}{gcd(a,b)}\) 得到原方程解。
欲求$$ax+by=gcd(a,b)$$则求$$bx+(a \bmod b)y=gcd(b,a\bmod b)$$已经得到得到变换后方程的解要倒推回原方程:设 \(x',y'\) 为新问题解,我们将 \(a\bmod b\) 写作 \(a-\lfloor \frac{a}{b} \rfloor \times b\)
其实就是(!!)把新的式子凑成 \(ax+by\) 的形式( \(ps:a,b\) 应为原问题的 \(a,b\) ),那么$$x=y'$$$$y=(x'-\lfloor \frac{a}{b} \rfloor \times y')$$
显然根据欧几里得算法最终会迭代成 \(x=1,y=0\) 的解,复杂度与欧几里得算法一样
基于欧几里得算法正确性 Bezout定理: \(ax+by=gcd(a,b)\) 必定有解得证。
注意一下指针的使用
点击查看代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n;
ll a,b;
ll exgcd(ll a,ll b,ll*x,ll*y){
if(b==0){
*x=1,*y=0;
return a;
/*
当b=0时 ax=a解为x=1 y可以为任意数,读者可以试试
*/
}
ll r=exgcd(b,a%b,x,y);
ll temp=*y;
*y=*x-a/b**y;
*x=temp;
return r;
}
ll x,y;
int main(){
cin>>a>>b;
cout<<exgcd(a,b,&x,&y);
cout<<" "<<x<<" "<<y<<"\n";
return 0;
}
我们若找到 \(ax+by=c\) 的一个解我们很容易得到更多的解,找到 \(k_1a=k_2b\) 容易发现 $$k1= \frac{b}{gcd(a,b)},k2=\frac{a}{gcd(a,b)}$$
我们可以调整 \(d\) 来调整解的取值(例如求正整数解)
例题
与同余的关系
若 \(a\bmod b = c\bmod b\) 则 \(a\equiv c (\bmod b)\)
不定方程与一次同余方程关系密切
一次同余方程 \(ax\equiv c (\bmod b)\) 等价于求解 \(ax+by=c\) ,里面每一组解的\(x_i\)都是同余方程解
应用
\(\begin{equation}
\left\{
\begin{alignedat}{}
m\equiv a_1 (\bmod b_1)\\
m\equiv a_2 (\bmod b_2)\\
m\equiv a_3 (\bmod b_3)\\
...
\end{alignedat}
\right.
\end{equation}\)
我们逐一满足,对于方程1 \(m=b_1x_1+a_1\),
方程2 $b_1x_1+a_1\equiv a2 \rightarrow b_1x_1\equiv a_2-a_1 (\bmod b_2) $ 转化为求解 \(b_1x_1+b_2x_2=gcd(b_1,b_2)\)
,利用扩展欧几里得算法可做,\(x_1\) 的范围会被约束:就像上文提到的会存在一个最小的
\(k1= \frac{b_2}{gcd(b_1,b_2)}\) , \({\forall}d{\in}Z\),\(m=b_1(x_1+dk_1)+a_1\)都为解
我们求得 \(x_1\) 后将其看做是常数有 \(m=b_1x_1+b_1\cdot dk_1+a_1 =b_1\cdot dk_1+(b_1x_1+a_1)\)
因为将 \(d\) 系数合并 \(b_1k_1=lcm(b_1,b_2)\)
\(m\) 于是被可表示成 \(m=lcm(b_1,b_2)\cdot d+(b_1x_1+a_1)\) (除了 \(d\) 之外我们都已经求得)变成方程一的解的形式 ,
对于方程3:其形式与求解方程2一致,我们重复上面步骤即可。这样我们就可以完成中国剩余定理的功能,也许定理是一种特殊的形式,作者对于数学还比较模糊,这里就不贴了说明了
代码:待补充
BSGS算法

浙公网安备 33010602011771号