初见安~本专题是基于读者对于线性同余方程的理解~建议先走走:传送门
这里是关于数论的专题(4)【详见数论专栏:)
1.中国剩余定理(CRT)
在n1, n2……nk两两互质的情况下,求解如下方程:
我们就需要用到中国剩余定理。
定理内容及求解过程如下:
设。并且有
这时我们就可以得到一个新的同余方程:
由此我们也可以解出x1,x2……xk。
所以总的方程解为:
这个定理是很好用的,至于解最后为什么是这么个形式,也是在反复利用gcd的特性,可以手动算一下试试:)(说白了就是自己证不来
*扩展中国剩余定理(exCRT)
扩展crt就是处理当n不一定为质数的情况,两两合并成x equiv r(mod lcm(n1, n2)),继续联立即可。【lcm:最小公倍数
,用扩欧定理可以解出k1和k2,带入即可。
举个例子:
对于前两个方程,有2 + 6 * x1 = 4 + 10 * x2,解得x1 = 2, x2 = 1,所以方程可以合并为:
,即
再与后面的方程合并求解即可。最后扩欧出来的就是答案。
在CRT上加几步操作即是了。
2.费马小定理
若p为一素数,且a、p互质(a 不等于p),则有:.。这个定理在求原根(传送门建设中)的时候会用到。
我们可以举个例子看看:求,我们可以通过定理
转化为:
所以在应用时我们还可以用到一个结论:
.
3.欧拉定理
费马小定理是欧拉定理的一个分支,也就是p为质数的情况。欧拉定理中:
如果a、n为正整数且互质,则有。在费马小定理中,φ(n) = n - 1。
所以欧拉定理总结起来有以下三种情况:
- a、n互质,
- a、n不互质,并且
,
- a、n不互质,并且
,直接暴力求
即可。
对于第二种情况的证明,建议多多参考别的博文……因为事实证明第二种和第三种是不能混用一个公式的,但是证着证着却又是可以共用的了。这里就不多说了。不过如果只存在第一种和第二种情况的话,是可以直接套用第二种的公式的。:)古代猪文就是一个很好的例子。
4.乘法逆元
当有a、n互质时,若有,则x是a关于n的逆元,记作
。注意,这里的-1并不是-1次方,而只是逆元的符号。作为-1次方时,
,但是作为逆元,是
,同余和等式的区别还是很大的:)
有一个结论:在(0, n ] 的范围内,逆元是唯一确定的。这个定理手算一下大概也都能明白。而设a在(0, n ] 内的逆元为x,a的逆元因为有乘上a有同余的性质,所以有。这样就可以表示出所有的逆元了。
那么如何求解逆元呢?有以下几种方法:
1)和求解线性同余方程一样,转化为求解一元二次方程ax + ny = 1,用扩展欧几里得定理求解。
2)用到欧拉定理可以得出: 两个基本式子,得到:
。
3)这样求逆元的话如果遇上数据量大了就很容易TLE,因为计算欧拉函数需要耗费大量时间。那么如何在线性时间里求出逆元呢?
以这么一个例题为背景——求解1~N中每个数的逆元。(mod p)
很明显N大一点儿时间复杂度就爆了。下面开始推导:
由取模这个操作的定义取余我们可以尝试这么来表示一下:
设(向下取整),
,则可得
。
转化为同余方程可得:。
所以在此基础上再乘上任何数都可以得到0,我们就可以构造:
由乘法分配律展开:
所以再替换回去可得:
这就是线性求解的递推转移方程啦!代码实现如下:
int inv[maxn];
inv[1] = 1;
for(int i = 2; i <= n; i++)
inv[i] = (p - p / i) * inv[p % i] % p;
4)其实更多的时候,我们用到逆元都是用来求组合数,也就是某个数的阶乘的逆元。对于这个,我们有个更直观的求解方法:
ll fac[maxn], inv[maxn];
fac[0] = inv[0] = 1;
for(int i = 1; i <=maxn; i++) fac[i] = fac[i - 1] * i % mod;
inv[maxn] = pow(fac[maxn], mod - 2);
for(int i = maxn - 1; i > 0; i--) inv[i] = inv[i + 1] * (i + 1) % mod;
很明显,因为inv[i]相当于是除以i的阶乘,所以就是。
第四行对于inv[maxn]的求法,其实是根据2)得到的。
以上就是这次讲解的全部内容啦!!!
迎评:)
——End——