同余问题
前言
我发现我的数论知识整理 , 整理的真的很乱,我觉得有必要重新整理梳理一下,就先从同余开始吧,前面的也没有什么可以梳理的,就是比较简单的结论和证明。(但也不代表本章很难,笔者是个 \(fw\) ,所以整理不出很 \(nb\) 的东西)
这篇文章能够提供什么学习内容,即这篇文章你能够学到什么 :
- \(1.\) 欧拉函数 \(\text{&}\) 欧拉定理
- \(2.\) 乘法逆元
- \(3.\) 扩展欧几里得
- \(4.\) 同余方程
- \(5.\) 中国剩余定理
一些表示
- \(1.\) \(\equiv\) 表示的模意义下相等
- \(2.\) \(\varphi\) 表示欧拉函数
- \(3.\) \(p\) 无特殊说明为一个质数。
同余的性质
- \(1.\) 自反性:\(a \equiv a (mod \ \ p )\)
- \(2.\) 对称性:\(a \equiv b, b \equiv a (mod \ \ p)\)
- \(3.\) 传递性:\(a\equiv b ,b\equiv c , a\equiv c(mod \ \ p)\)
- \(4.\) 满足运算律 \(a \equiv b , c \equiv d , a\bigoplus c \equiv b\bigoplus d(mod \ \ p)\)
\(\bigoplus\) 代表运算。
虽然说很显然,但是也是需要放在前面的。
还有就是,对负数取模的时候, \(ret = (ret + mod) \text{%} mod\) , 当然,不要 \(define\ \ int \ \ unsigned\ \ long\ \ long\) , 该事例来源于机房某憨批。
欧拉函数 & 欧拉定理
首先声明,欧拉函数是没有欧拉定理的。
欧拉函数
\(\varphi(N)\) 为欧拉函数,为 \([1,N]\) 中与 \(N\) 互质的数的个数。
一个小定理 :
- \(N = \prod_{\rm{p|N}}{p_i}^{c_i}\)
\(\varphi(N) = N \times \prod_{p|N}(1 - \frac{1}{p})\)
证明 : 涉及一个容斥原理。
我们设 \(N\) 的一个质因子为 \(p\) , 那么 \(p\) 的倍数有 \(\frac{N}{p}\) 个,同理,若 \(q\) 也是 \(N\) 的一个质因子,那么 \(q\) 的倍数有 \(\frac{N}{q}\) 个,
我们去掉这些数 (因为不能有互质的,\(N\) 和他们的最大公约数都不是,是 \(p\) 或 \(q\)) .
那么我们就删掉了 \(pq\) 的倍数两次,给它加回来(容斥) 。
那么最后我们能得到 \(N - \frac{N}{p} - \frac{N}{q} + \frac{N}{pq} = N\times (1 - \frac{1}{p})\times (1 - \frac{1}{q})\)
如果需要计算欧拉函数的话,我们就根据上述,直接搞一个质因数的分解,顺带求出欧拉函数。
欧拉定理
若正整数 \(a , n\) 互质,则 \(a^{\varphi(n)} \equiv 1(mod \ \ p)\) 。
证明 : 咕了。
欧拉定理的推论
若正整数 \(a,n\) 互质,则对于任意的正整数 \(b\) ,有 \(a^b \equiv a^{b \ \ mod \ \ \varphi(p)} (mod \ \ p)\)
证明:来源:抄书
设 \(b = q \times \varphi(p) + r\) , 其中 $ 0 \leq r < \varphi(p) $ , 即 \(r = b \ \ mod \ \ \varphi(p)\)
\(a^b \equiv a^{q\times \varphi(p) + r}\equiv a^{\varphi(p)^q}\times a^r \equiv 1^q \times a^r \equiv a^r \equiv a^{b \ \ mod \ \ \varphi(p)} (mod \ \ p)\)
得证。
扩展欧拉定理
证明 : 且咕。
乘法逆元
为什么这里要说一下乘法逆元呢? 首先是这里有时候会
因为在模运算中,是不支持除法的,但是我们可以将 \(\frac{a}{b}\) 转化成 \(a\times b^{-1}\) 的乘法,那么我们这个时候只需要求解出 \(b^{-1}\) 就好了,你可能会说,这不就是 \(\frac{1}{b}\) 吗? 的确,但是你要明白的是,模运算不支持除法。所以,我们求解 \(b^{-1}\) 就不能直接 \(\frac{1}{b}\)
- 事先说明 \(b^{-1}\) 已经不是 \(\frac{1}{b}\) ,而是代表着 \(mod \ \ p\) 意义下的逆元。
我们继续探寻一下这个逆元的性质 ,也就是 \(b \times b^{-1} \equiv 1(mod \ \ p)\)
我们探讨一下求解的方法
递推式法
确切地来说,这种方法是最容易理解的一种了。 推点式子嘛。
我们假设 \(p = k \times i + r\) , 则显然是有
那么显然我们同样是可以知道的, \(k = \lfloor\frac{p}{i}\rfloor , r = p \text{%} i\)
那么我们显然 \(r < i\) ,那么我们就有递推式
inv[1] =1 ;
for(qwq int i = 2 ; i <= n ; i++)
inv[i] = (- p / i + p) * f[p % i] ;
费马小定理求解逆元
这里必须保证 \(p\) 为质数。
证明:咕了。
上文还有一个欧拉定理求解的。
下文还有一个扩展欧几里得求解的。
扩展欧几里得
首先你需要明白什么是欧几里得。
裴蜀定理
对于任意的正整数 \(a , b\) 若存在正整数 \(x ,y\) 使得式子 \(ax + by = m\) , 则 \(gcd(a ,b)|m\)
证明 : 我们不断的递归 \(gcd(a , b)\) ,显然递归到最后一层 ,就是当 \(x = 1 , b = 0\) 的时候,有一个特殊解 , 无论 \(a\) 取什么值,都有 \(a \times 1 + 0 \times 0 = gcd(0 , a)\) .
然后求解 \(gcd\) 的过程是递归回溯找到的,那么也就会有 \(gcd(b , a \text{%} b) = gcd(a , b)\) .现在我们假设存在一组解 \(x , y\),使得其一定满足于 \(b\times x + (a \text{%}b)\times y = gcd(b , a \text{%} b)\) , 则又因为 \(a \text{%} b = a - \lfloor\frac{a}{b}\rfloor\times b\) , 带入式子我们就有\[b\times x + (a - \lfloor\frac{a}{b}\rfloor\times b)\times y = gcd(a , a \text{%}b) \]这也就等价于
\[bx + (a - \lfloor\frac{a}{b}\rfloor\times b) \times y <=> ay - b\times (x - \lfloor\frac{a}{b}\rfloor)\times y \]然后我们就得到了通解,继续向上不断的寻找,递归到顶部,最后一定能实现,这时候我们不仅证出了结论,亦求解了出来。
- 应用
- \(1.\) 判断不定方程 \(ax + by = m\) 是否有解
- \(2.\) 求解出不定方程 \(ax + by = m\) 的解。
扩展欧几里得求解逆元
扩展欧几里得求解逆元其实就是对应着求解不定方程对应着 \(1\) 的情况 。 直接求解即可。 这里给出扩展欧几里得求解不定方程的代码 :
void exgcd(int a , int b , int &x , int &y) //这里直接传下去,就不用设置全局变量了
{
if(!b) return (void) (x = 1 , y = 0) ;//某人竟然以为会CE
exgcd(b , a % b , x , y) ;
int k = x ; x = y ; y = k - y * (a / b) ;
}
扩展欧几里得求解线性同余方程
我们这货和求解逆元长得很像,其实求解逆元就是这个一个特例。
这个同余方程等价于 \(ax + py = c\)
然后这货就和不定方程一样了。 直接 \(exgcd\) 求解即可。
中国剩余定理
又称孙子定理。(什么傻逼名字)
普通中国剩余定理
中国剩余定理也就是让你求解一个线性同余方程组。
即为:
如果 \(p_i\) 均互质,那么我们称其为中国剩余定理,当然如果不互质,我们叫他扩展中国剩余定理,最后求解出来的是 \(x\) 的最小值。
- 一些变量设置 :
- \(1.\) \(M = \prod_{i = 1}^{n}p_i\)
- \(2.\) \(m_i = \frac{M}{p_i}\)
- \(3.\) \(inv_i\) 表示 \(m_i\) 在 \(mod \ \ M\) 意义下的逆元。
则 \(x = \sum_{i = 1}^{n} m_i \times inv_i \times a_i\)
证明:
证明这东西搞懂搞不懂都行,记住也可以
\(emm\), 我们直接选择带入反向验证是否是正确的,只要是正确的,那么我最后是 \(mod \ \ M\) 的 ,最小值显然是不必担心的。我们发现 \(\forall k \neq i , a_i \times inv_i\times m_i \equiv 0 (mod \ \ p_k)\) , 带入则显然是成立的。
甚至说,中国剩余定理你都可以不用掌握,直接来到 \(excrt\) 也是可以的。
void exgcd(int a , int b , int &x , int &y)
{
if(!b) return (void) (x = 1 , y = 0) ;
exgcd(b , a % b , x , y) ;
int k = x ; x = y ; y = k - y * (a / b) ;
}
void init()
{
for(qwq int i = 1 ; i <= n ; i++)
{
a[i] = read() , p[i] = read() ; //剩余 a_i 条猪
M = M * p[i] ;
}
for(qwq int i = 1 ; i <= n ; i++)
{
int mi = M / p[i] ;
exgcd(mi , p[i] , x , y) ;
s = (s + mi * x * a[i]) % M ;
}
}
扩展中国剩余定理
这个时候还是求解线性同余方程组
但是这时候已经不满足 \(p_i\) 互质了,我们考虑这个问题就只有一个我们是否可以修复呢?很显然答案是否定的。因为在 \(p_i\) 不互质的情况下, \(inv\) 可能不存在导致整个算法是错误的。
既然都是合并同余方程组来解决问题的,我们同样也是来合并一下。根据线性同余方程我们可以知道上面的两个式子等价于
我们就知道 \(a_1 + p_1k_1 = a_2 + p_2k_2\) , 然后我们继续随便搞一下 \(p1k_1 - p_2 k_2 = a_1 - a_2\) , 我们发现这个和上述 \(ax + by = c\) 有着相同的形式,其中 \(a_1 , a_2 ,p_1 ,p_2\) 均为已知量,在模 \(\frac{p_1p_2}{gcd(p_1 , p_2)}\) 时成立。
然后我们就有了一个 \(x = k_1p_1(mod \ \ (\frac{p_1p_2}{gcd(p_1 , p_2)}))\)
inline int poow(int a , int b , int mod)
{
int ret = 0 ;
while(b)
{
if(b & 1) ret = ( ret + a ) % mod ;
a = a + a % mod ;
b >>= 1 ;
}
return ret ;
}
inline void exgcd(int a , int b , int &x , int &y)
{
if(!b)
{
x = 1 , y = 0 ;
return ;
}
exgcd(b , a % b , x , y) ;
int k = x ;
x = y ;
y = k - (a / b) * y ;
}
inline int query()
{
int M = a[1] , ans = b[1] , x , y;
for(int i = 2 ; i <= n ; i++)
{
int k = M , l = a[i] , c = (b[i] - ans % l + l) % l ;
int gcd = Base::Gcd(k , l) , lcm = l / gcd ;
exgcd(k , l , x , y) ;
if(c % gcd != 0 ) return -1 ;
x = poow(x , c / gcd , lcm) ;
ans += x * M ;
M *= lcm ;
ans = (ans % M + M) % M ;
}
return (ans % M + M) % M ;
}