模运算和同余以及欧几里得
updata on 2020.3.19
更新了exgcd部分,感觉以前并没有真正理解
并将crt部分放到了一篇单独的blog感觉以前对crt的学习也不深入
updata on 2020.3.31
这部分时间想着重做做数论,然后加入了#2同余部分
又修改了 exgcd 里的一个笔误
updata on 2020.4.1-2020.4.5
断断续续的加入同余结论的部分证明和辗转相除的证明,把欧拉定理放到了积性函数那篇文章并添加证明
1.取模
1.1同余
若\((a-b) \bmod n=0\),则a与b同余:
a,b为正整数时,等价于:
1.2性质
- k为正整数,有:
\(a \bmod n=(a \bmod kn) \bmod n\) - 若\(k \mid a\),有:
\(\frac{a}{k} \bmod n=\frac{a \bmod kn}{k}\)
1.3龟速乘
加倍求积法
LL mul(LL a,LL b){
LL ret=0;
for(;b;b>>=1){
if(b&1) ret=(ret+a)%p;
if(b>1) a=(a+a)%p;
}
return ret;
}
1.4快速幂
平方求幂法
LL pow(LL a,LL b){
LL ret=1;
for(;b;b>>=1){
if(b&1) ret=(ret*a)%p;
if(b>1) a=(a*a)%p;
}
return ret;
}
1.5long double实现64位模乘法
long double类型在乘爆后只保留前几位,也就是较大几位。除以n后的结果主要为较大几位贡献,所以舍去低位对结果的偏差不大(一以内)
为防止减出负数,加p再取模
LL mul(LL a,LL b,LL p){
LL q=(long double)a*b/p;
return (a*b-q*p+p)%p;
}
2同余
总所周知,\(a\equiv b \pmod p\)表示\(a \bmod p=b \bmod p\)
那么下面给出一些性质,大部分都很好理解,摘自维基百科
经常用的也就上面这些
大部分比较显然,然而那个\(n\)次方的我也不会证,就简单证一下最后那个放大缩小模数
\(a\equiv b\pmod m\),则可设\(a=pm+w,b=qm+w\)
那么\(ka\bmod km =(kpm+kw)\bmod km=kpm\bmod km+kw\bmod km=w\bmod m\)
同样,\(kb\bmod km=w\bmod m\)
又由于上面每一步可逆,所以\(a\equiv b\pmod m\Leftrightarrow ak\equiv bk\pmod {km}\)
这部分尤其是那个除法原理2,我也没怎么看,先放这里
关于除法原理1:
由于\(\gcd(k,m)=1\),那么就是说\(k,m\)的质因数全都互不相同,所以\(a\equiv ka\pmod m\)
所以上面那个式子更完整可以表述为\(a\equiv b\equiv ka\equiv kb\pmod m\)
3逆元
a为整数,n为正整数,若整数b满足:
\(ab \bmod n=1\)
则b为a模n的逆元,记为\(a^{-1}\)或\(\frac{1}{a}\)
3.1一些结论
- 当且仅当\(gcd(a,n)=1\),a模n的逆元存在
- 若\(b_1,b_2\)为a模n的逆元,则必有\(b_1 \equiv b_2 \pmod b\)
即a模n的逆元在模n意义下唯一
3.2费马小定理
设p为质数,a为与p互质的整数,则有:
3.2.1证明
(p-1个数\(\bmod p\)意义下互不相同,因为\(a^{-1}\)存在,每个数都乘\(a^{-1}\)会变回原数列)
(p为质数,\(gcd(p,(p-1)!)=1\),所以存在\(((p-1)!)^{-1}\))
3.2.2通过费马小定理求逆元
从而快速幂算逆元
3.3预处理逆元
3.3.1法一
设i为\([1,n]\)之间的整数,有:
\(p=\lfloor \dfrac{p}{i} \rfloor i+(p \bmod i)\)
从而有(放在mod p下后,左边的p等于0):
\(\dfrac{1}{i} \equiv - \dfrac{\lfloor \frac{p}{i} \rfloor}{p \bmod i} \pmod p\)
因为\(p \bmod i<i\),可以\(O(n)\)递推算
3.3.2法二
由于\(\dfrac{1}{i!}=\dfrac{i+1}{(i+1)!}\),则\(O(\log p)\)算出\(\dfrac{1}{n!}\),再\(O(n)\)算所有的\(\dfrac{1}{i!}\),从而算出\(\dfrac{1}{i}\)
void niyuan(){//f阶乘数组,h逆元数组,g阶乘的逆元数组
f[0]=1;
for(int i=1;i<=n;i++) f[i]=(LL)f[i-1]*i%p;
g[n]=pow(f[n],p-2);//根据费马小定理
for(int i=n-1;i;i--) g[i]=(LL)g[i+1]*(i+1)%p;
for(int i=1;i<=n;i++) h[i]=(LL)g[i]*f[i-1]%p;
}
3.4欧拉定理
欧拉定理也可以求逆元
设\(n \geq 2\)为整数,\(gcd(a,n)=1\),则有:
\(a^{\varphi(n)} \equiv 1 \pmod n\)
由此可用:
\(a^{-1} \equiv a^{\varphi(n)-1} \pmod n\)
求出逆元,但计算\(\varphi(n)\)的复杂度较高,一般不这么用
更详细的欧拉定理看这里
4欧几里得算法
4.1欧几里得
这个东西说的是\(\gcd(a,b)=\gcd(b,a\bmod b)\),然后就可以递归的求解\(\gcd(a,b)\)
设\(d=\gcd(a,b)\)
则可以令\(a=nd,b=md\),那么\(a-b=(n-m)d\)
又由于\(\gcd(n,m)=1\Rightarrow \gcd(n-m,m)=1\)(为什么这样下面说),所以\(\gcd(a,a-b)=\gcd(nd,(n-m)d)=1\)
那么,当\(a\ge b\),就可以让\(a\)不断减\(b\)直到\(a<b\),就等价于\(a\bmod b\)
设\(\gcd(n-m,m)=k\),同样可以这样表示:\(n-m=pk,m=qk\)
那么,\(a=nd=(pk+qk)d,b=md=qkd\)
此时,又因为\(\gcd(a,b)=\gcd((pk+qk)d,qkd)=d\)
所以\(\gcd((p+q)k,qk)=1\),那么显然\(k=1\)
4.2扩展欧几里得算法
此方法可以求解\(ax+by=\gcd(a,b)\)中的\(x,y\)
考虑这个问题,如果\(b=0\),那么显然,\(\gcd(a,b)=a,x=1,y\)为任意数
如果\(b\neq 0\),我们设:
\(\gcd(a,b)=ax_1+by_1\)
\(\gcd(b,a\bmod b)=bx_2+(a\bmod b)y_2=bx_2+(a-\lfloor\dfrac{a}{b}\rfloor b)y_2\)
\(ax_1+by_1=ay_2+b(x_2-\lfloor \dfrac{a}{b}\rfloor y_2)\)
所以:\(x_1=y_2,y_1=x_2-\lfloor \dfrac{a}{b}\rfloor y_2\)
可以据此写出代码
这样可以求模数不为质数的逆元
void exgcd(LL a,LL b,LL &x,LL &y){
if(!b){
x=1;y=0;
return;
}
exgcd(b,a%b,x,y);
LL tmp=x;x=y;
y=tmp-a/b*y;
}
}
5中国剩余定理
此部分新开了一篇blog讲,原来讲的并不清楚