數論-模運算,歐幾里得,擴充套件歐幾里得
一:模運算
1:餘數:a對b取模的結果就是a除以b的餘數,記作a%b。例如24%5 == 4
2:性質:
\[ (a+b)\%p=(a\%p+b\%p)\%p \]
\[ (a-b)\%p=(a\%p-b\%p+p)\%p \]
\[ (a*b)\%p=(a\%p)*(b\%p)\%p \]
二:最大公約數
1:約數:如果a%x==0,我們稱x是a的約數(或因數)。
2:倍數:如果a%x==0,我們稱a是x的倍數。
3:a與b的最大公約數:是指一個最大整數x既是a的約數也是b的約數,記作gcd(a,b)。
4:演算法公式:
\[ gcd(a,b)=\begin{cases} a & b=0 \\ gcd(b,a\%b) &b!=0 \\ \end{cases} \]
5:程式碼實現:
int gcd(int a,int b)
{
if(b==0)
return a;
else
return gcd(b,a%b);
}
6:證明:
\[ gcd(a,b)=gcd(b,a\%b) \]
設
\[ gcd(a,b)=d \]
則
\[ a = nd, b = md,gcd(n,m) =1 \]
又
\[ a\%b = a-\lfloor \frac{a}{b} \rfloor*b=nd-\lfloor \frac{nd}{md} \rfloor*md=(n-\lfloor \frac{n}{m} \rfloor*m)*d=(n\%m)*d \]
所以
\[ gcd(b,a\%b)=gcd(md,(n\%m)*d)=d*gcd(m,n\%m) \]
因此只要證明
\[ gcd(m,n\%m)=1 \]
假設
\[ gcd(m,n\%m)=q,gcd(m,n\%m)!=1 \]
設
\[ n = k*m+r,0<=r<m \]
則
\[ n\%m=r,gcd(m,r) = q \]
設
\[ m = m1*q; r = r1*q \]
那麼
\[ n = k*m1*q+r1*q = (k*m1+r1)*q \]
那麼q就是n和m的最大公約數,與我們所假設的gcd(n,m)=1矛盾。所以
\[ gcd(m,n\%m)=1 \]
所以
\[ gcd(a,b)=gcd(b,a\%b) \]
7:相關性質
\[ gcd(a,b,c)=gcd(a,gcd(b,c)) \]
三:最小公倍數
1:最小公倍數:將a與b的最小公倍數記作lcm(a,b).
2:與最大公約數的關係:
\[ gcd(a,b) = \frac{a}{lcn(a,b)}*b \]
注意:先除後乘防止溢位。
3:相關性質
\[ lcm(a,b,c) = lcm(a,lcm(b,c)) \]
注意:lcm(a,b,c) != abc/gcd(a,b,c)
四:擴充套件歐幾里得
1:用途:擴充套件歐幾里得演算法用於解決這樣一個問題,給定正整數a,b,求ax+by=gcd(a,b)的一組解。
2:遞迴求解(核心思想)
已知:
\[ gcd(a,b) = gcd(b,a\%b) \]
則
\[ a*x+b*y = gcd(a,b) =>b*x1+a\%b*y1 = gcd(b,a\%b) \]
假設x1,y1為方程組的一組解。那麼:
\[ a*x + b*y = gcd(a,b) = b*x1+a\%b*y1 = b*x1+(a-\lfloor\frac{a}{b}\rfloor*b)*y1 = a*y1+b*(x1-\lfloor\frac{a}{b}\rfloor*y1) \]
所以:
\[ x = y1; y = x1-\lfloor\frac{a}{b}\rfloor*y1 \]
當b==0時,a=1。此時的一組解是
\[ x==1,y==0 \]
3:程式碼實現
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x = 1;
y = 0;
return a;
}
int gcd = exgcd(b,a%b,y,x);
y -= a/b*x;
return gcd;
}
4:推廣
以上我們可以求出ax+by=gcd(a,b)的任意一組整數解,但是如何求ax1+by1=c這種呢?如果要求x>0且最小呢?
如果
\[ c\%gcd(a,b)=0 \]
否則無解。
簡單證明:
假設
\[ k = \frac{c}{gcd(a,b)} \]
則
\[ a*x1+b*y1=c => a*k*x2+b*y*k2 = gcd(a,b)*k = c \]
所以
\[ x1 = k*x2,y1 = k*y2 \]
如何求x非負且最小呢?
我們假設已經得到ax+by=c的一組解
令
\[ g =gcd(a,b) \]\[ lcm(a,b) = \frac{a}{g}*b \]
可得
\[ a*x+lcm(a,b)+b*y-lcm(a,b) = c \]
所以
\[ a*(x+\frac{b}{g})+b*(y-\frac{a}{g}) = c \]
所以可知x加上或減去任意倍數的b/gcd(a,b)後均有的y的解。
令
\[ t = gcd(a,b) \]
則x的最小非負解為
\[ (x\%t+t)\%t \]