模拟赛考完,感觉自己数论弱爆了,来写写总结。
QAQ
1.exgcd
先写写推导过程吧:
对于方程 ax+by = gcd(a,b) 和 bx’+(a%b)y‘ = gcd(b,a%b)
因为 gcd(a,b) == gcd(b,a%b)
所以 ax+by == bx’+(a%b)y‘
拆开,再合并得: ax+by == ay'+b(x'-[a/b]*y')
so , code
1 int exgcd(int a,int b,int &x,int &y) 2 { 3 if(!b) 4 { 5 x=1; y=0; 6 return a; 7 } 8 int g=exgcd(b,a%b,y,x); 9 y-=a/b*x; 10 return g; 11 }
2.CRT
中国剩余定理CRT(Chinese Remainder Theorem)
中国剩余定理给出了以下的一元线性同余方程组:
有解的判定条件,并用构造法给出了在有解情况下解的具体形式。
![](https://gss0.bdstatic.com/94o3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D223/sign=afd164d67a310a55c024d9f684444387/7af40ad162d9f2d30fcbdacaaaec8a136327cc39.jpg)
![](https://gss3.bdstatic.com/7Po3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D203/sign=56bcfe3fc55c1038207ec9c28110931c/91ef76c6a7efce1b22fa36efac51f3deb58f65c6.jpg)
![](https://gss3.bdstatic.com/-Po3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D59/sign=98cf0fe8ff039245a5b5e10687947d4e/562c11dfa9ec8a133826aec5f403918fa0ecc0d3.jpg)
![](https://gss2.bdstatic.com/-fo3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D20/sign=3421af3261d0f703e2b292dc08fa9d75/91ef76c6a7efce1b232431efac51f3deb48f658c.jpg)
![](https://gss2.bdstatic.com/9fo3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D17/sign=9757be9e4410b912bbc1f2f9c3fd6213/f3d3572c11dfa9ecd055af3261d0f703918fc198.jpg)
![](https://gss0.bdstatic.com/-4o3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D14/sign=600e2894abcc7cd9fe2d30dd3801d19f/dcc451da81cb39db7a5c542fd8160924ab18302e.jpg)
![](https://gss2.bdstatic.com/-fo3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D20/sign=987bd370be003af349badb60342ace9c/d0c8a786c9177f3ec9a1cf7478cf3bc79f3d5635.jpg)
![](https://gss2.bdstatic.com/-fo3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D17/sign=41ce7c820246f21fcd345a54f624e601/dc54564e9258d10925da9bcbd958ccbf6c814d89.jpg)
![](https://gss1.bdstatic.com/9vo3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D270/sign=1e2b1996a1ec8a13101a50e7c7039157/5ab5c9ea15ce36d39c3ebe4932f33a87e950b194.jpg)
在模的意义下,方程组
只有一个解:
——百度百科
具体说说,如果我们要构造一个合法解,那么考虑对于其中任意的一个方程 i ,应该如何构造:
首先,我们要保证 x mod mi == ai 那么x 应该加上 ai ,但会发现这会对其他方程产生影响
所以为了消除对其他方程的影响,我们应该加上 ai × ( M/mi ) ,但又会发现 x 又不满足mod mi 余 ai 了
所以实际我们应该给 x 加上 ai × (M/mi) × (M/mi)-1 ,(这个逆元是mod mi 意义下的)
so,code
1 int CRT() 2 { 3 int M=1,x=0; 4 for(int i=1;i<=n;i++) M*=m[i]; 5 for(int i=1;i<=n;i++) 6 { 7 int tmp=M/m[i]; 8 int t=qpow(tmp,m[i]-2,m[i]); 9 x=(x+a[i]*tmp*t)%M; 10 } 11 return x; 12 }
3.Lucas
当遇到组合数的计算时,若模数小于计算中阶乘的数时,不能直接对阶乘取模,此时便需要用到Lucas定理:
$ C_n^m equiv C_{n/p} ^ {m / p} imes C_{n\%p}^{m\%p} mod p $ (p为质数)
当 n,m 均小于p时计算,一直递归就行了
so,code
1 int C(int n,int m) 2 { 3 if(n<m) return 0 4 return fac[n]*inv[m]%p*inv[n-m]%p; 5 } 6 int Lucas(int n,int m) 7 { 8 if(n<m) return 0; if(!n) return 1; 9 return Lucas(n/p,m/p)*C(n%p,m%p)%p; 10 }