零,前言:
学chty_sqy开个数论集合
学OI的时候一看数论就头大,现在该还了 T_T
建议推导和证明不熟或不会的同学动手推导
而且公式看上去不太清楚,学习的同学请仔细阅读
以前数论怎么都学不会,主要还是浮躁,不仔细看,没有动手 orz
一,gcd(欧几里得算法):
两个数a和b的最大公因数被称为gcd(a, b)
求gcd通常用欧几里得算法
原理:gcd(a, b)=gcd(b, a%b)
详情:https://www.cnblogs.com/cdcq/p/11366100.html
代码:
1 int gcd(int a,int b){ return b ? gcd(b,a%b) : a;}
二,exgcd(扩展欧几里得算法):
数论守门员
有一个或者几个变量的整系数方程,它们的求解仅仅在整数范围内进行。
扩展欧几里得算法研究的是形如 a*x+b*y=c 的丢番图方程的解
方程有解当且仅当gcd(a, b)|c
原理:a*x1+b*y1=gcd(a, b),b*x2+(a%b)*y2=gcd(b, a%b),gcd(a, b)=gcd(b, a%b) => x1=y2,y1=(x2-⌊a/b⌋*y2)
详情:https://www.cnblogs.com/cdcq/p/11366100.html
代码:
1 void exgcd(int a,int b,int &x,int &y){ 2 if(!b){ 3 x=1,y=0; 4 return ; 5 } 6 exgcd(b,a%b,x,y); 7 int z=x; 8 x=y,y=(z-a/b*y); 9 }
例题:
洛谷4549 裴蜀定理
洛谷1516 青蛙的约会
洛谷3951 小凯的疑惑
洛谷1082 同余方程
三,中国剩余定理(crt):
今有物不知其数,三三数之剩二;五五数之剩三;七七数之剩二。问物几何?
一次同余方程组是指形如x≡ai(mod mi) (i=1,2,…,k)的同余方程构成的组
中国剩余定理的主要用途是解一次同余方程组,其中m1,m2,...,mk互质
原理:构造一个解x=∑ai*M/mi*ti,其中ti为同余方程M/mi*ti≡1(mod mi)的最小正整数解,ti可用exgcd求出
详情:https://www.cnblogs.com/cdcq/p/11373544.html
代码:
(其中LL是long long,qcm是快速乘)
1 LL crt(){ 2 LL bwl=0; 3 for(int i=1;i<=k;++i){ 4 LL x,y; 5 exgcd(M/m[i],m[i],x,y); 6 if(x<0) x=x%m[i]+m[i]; 7 bwl=(bwl+qcm(qcm(a[i],M/m[i]),x))%M; 8 } 9 return (bwl+M)%M; 10 }
例题:
洛谷3868 猜数字
四,扩展中国剩余定理(excrt):
扩展中国剩余定理的主要用途是解一次同余方程组,其中m1,m2,...,mn不一定互质
原理:由前k-1个方程组成的方程组的通解x+t*M,令x+t*M≡ak(mod mk)构造出前k个方程的解,t可用exgcd求出
若x+t*M≡ak(mod mk)无解,则整个同余方程组无解
详情:https://www.cnblogs.com/cdcq/p/11373544.html
代码:
(其中LL是long long,qcm是快速乘,三个参数分别为两个乘数和模数)
1 LL excrt(){ 2 LL M=m[1],ans=a[1]; 3 for(int i=2;i<=k;++i){ 4 LL x,y; 5 LL d=gcd(M,m[i]); 6 LL c=(a[i]-ans%m[i]+m[i])%m[i]; 7 if(c%d) return -1; 8 exgcd(M,m[i],x,y); 9 x=qcm(x,c/d,m[i]/d); 10 ans+=qcm(x,M,M*m[i]); 11 M*=m[i]/d; 12 ans=(ans%M+M)%M; 13 } 14 return ans; 15 }
例题:
洛谷4777 扩展中国剩余定理