数论-模运算,欧几里得,扩展欧几里得

一:模运算

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 \]

五:扩展欧几里得可以用来做什么呢?
1:求解线性方程

HDU2669Romantic

2:求解同余方程

POJ1061青蛙的约会

3:求逆元

https://www.cnblogs.com/AC-AC/p/10042675.html

猜你喜欢

转载自www.cnblogs.com/AC-AC/p/10065723.html