蒟蒻这几天比较闲,于是自学了早就学了很久的扩欧与中国剩余定理。。。。。。
--------------------------------------------------------------------------------------------------------------扩展欧几里德------------------------------------------------------------------------------------------------------- 扩展欧几里德算法(用于求解px+qy=gcd(p,q)类问题):
px+qy=gcd(p,q) 记n=gcd(p,q) 则:
y=(n-px)/q=[n-(p mod q)x]/q-[p/q]x (p mod q=p-[p/q])
记y0=x x0=[n-(p mod q)x]/q=[n-(p mod q)y0]/q
其等价于 qx0+(p mod q)y0=n-(p mod q)y0+(p mod q)y0=n
递归求解即可; code(求ax+by=gcd(a,b)的一组可行解):
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int a,b,x,y; void exgcd(int a,int b) { int t; if (a%b==0) { x=0; y=1; } else { exgcd(b,a%b); t=x; x=y; y=t-(a/b)*y; } } int main() { scanf("%d%d",&a,&b); exgcd(a,b); printf("%d %d\n",x,y); }
若要求解最小正整数,分别将x,y对lcm(a,b)取模 (lcm(a,b)*gcd(a,b)=a*b)
那么,我们既可以解决类似于 ax=c (mod b) 的同余方程最小解(满足 c|gcd(a,b))
我们可以将ax=c (mod b) 转化为 ax+by=c 的最小解,那么我们可以求出 ax+by=gcd(a,b) 再将 x 乘上 c/gcd(a,b) 即可(最后模去b)
code:
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int a,b,c,x,y,gcd; void exgcd(int a,int b) { int t; if (a%b==0) { x=0; y=1; gcd=b; } else { exgcd(b,a%b); t=x; x=y; y=t-(a/b)*y; } } int main() { scanf("%d%d%d",&a,&b,&c); exgcd(a,b); x=(x%b+b)%b; x=x*(c/gcd); x%=b; printf("%d\n",x); }那么我们就解决了线性同余方程,那么问题来了,线性同余方程组怎么办?
-------------------------------------------------------------------------------------------------------中国剩余定理--------------------------------------------------------------------------------------------------------------
远离不再赘述,我在此只给出总式
已知 x=b1(mod m1) x=b2(mod m2)......x=bi(mod mi)......x=bn(mod mn) N=m1+m2+m3+........+mn
则x=
exgcd(a,b)返回以上程序的x
code:
#include<cstdio> using namespace std; int b[100],m[100]; int n,x,y,N; void exgcd(int a,int b) { int t; if (a%b==0) { x=0; y=1; } else { exgcd(b,a%b); t=x; x=y; y=t-(a/b)*y; } } int main() { int i,now,ans; scanf("%d",&n); N=1; ans=0; for (i=1;i<=n;++i) { scanf("%d%d",&b[i],&m[i]); N=N*m[i]; } for (i=1;i<=n;++i) { now=N/m[i]; now=now%m[i]; exgcd(now,m[i]); x=(x%m[i]+m[i])%m[i]; x=(x*(N/m[i])*b[i])%N; ans=(ans+x)%N; } printf("%d\n",ans); }---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Lcomyn