什么是同余定理?相比大家都知道,简单来说就是一个公式
如果a=b(mod m),那么我们称a,b关于模m同余,这个式子叫做同余式。
定理1.若a=b(mod m),且c=d(mod m),那么ax+cy=bx+dy(mod m),同余式满足加法
定理2.若a=b(mod m),且 c=d(mod m),那么,ac=bd(mod m),同余式满足乘法
定理3.若a=b(mod m),那么gcd(a,m)=gcd(b,m)
定理4.若a=b(mod mi),其中1<=i<=n,当且仅当a=b(mod[m1,m2,m3,…,mn]),这里[m1,m2,m3,…,mn]表示m1,m2,m3,…,mn的最大公约数gcd
定理5.若ac=bc(mod m),那么a=b(mod m/gcd(c,m)),如果gcd(c,m)=1,那么a=b(mod m)
定理6.若a=b(mod m),且d丨m,那么a=b(mod d)
定理7.若a=b(mod m),那么a+c=b+c(mod m),且a-c=b-c(mod m),满足加法
线性同余方程
1.解一元线性同余方程组
推导过程
x≡r1(mod m1)
x≡r2(mod m2)
上面的方程组就等价于
x=r1+m1y1(一式)
x=r2+m2y2(二式)
那么就有r1+m1y1=r2+m2y2,则(r2-r1)=(m1y1-m2y2)
令d=gcd(m1,m2),那么(r2-r1)/d=m1y1/d-m2y2/d
-> (r2-r1)/d-m1y1/d=0(mod m2/d)
-> (r2-r1)=m1y1(mod m2/d)
-> y1=(r2-r1)/m1(mod m2/d),所以一定存在一个最小正整数y’使得y1=y’(mod m2/d),令y1=y’+(m2/d)C,C是一个常数 ,将y1带入一式得x=r1+m1(y’+(m2/d)C)
-> x=r1+m1y’+(m1m2/d)C
-> x=r1+m1y’(mod m1m2/d)
模板代码:
#include<iostream>
using namespace std;
typedef long long ll;
void exgcd(ll &x,ll &y,ll &g,ll a,ll b)
{
if(b==0)
{
g=a;
x=1;
y=0;
return ;
}
else
{
ll x1,y1;
exgcd(x,y,g,b,a%b);
x1=y;
y1=x-(a/b)*y;
x=x1;
y=y1;
}
return ;
}
ll solve(ll n)
{
int flag=1;
ll a1,r1;
cin>>a1>>r1;
for(ll i=2;i<=n;i++)
{
ll a2,r2,y1,y2,g;
cin>>a2>>r2;
ll c=r2-r1;
exgcd(y1,y2,g,a1,a2);
y1=y1*c/g;
ll s=a2/g;
y1=(y1%s+s)%s;//这里为了防止y1出现负数的情况
if(c%g)
{
flag=0;
}
r1=r1+y1*a1;
a1=a1*a2/g;
}
if(flag==0) return -1;//-1表示无解
return r1;
}
int main()
{
ll n;
while(scanf("%lld",&n)!=EOF)
{
cout<<solve(n)<<endl;
}
return 0;
}