问题
就是让你求解同余方程
前言
如果所有的模数互质,那么是可以用中国剩余定理求解的,并且代码特别的段
但是如果不互质的话,如果你要用中国剩余定理来解的话就显得没这么方便了,因为你在求那个类似逆元的东西不好求,并且暴力求的话时间也不允许
所以就需要一个更优秀的东西来解
解法
我们观察两个同余方程
x≡a1(modm1)
x
≡
a
1
(
m
o
d
m
1
)
x≡a2(modm2)
x
≡
a
2
(
m
o
d
m
2
)
其实这个可以写成以下形式
x−y1∗m1=a1
x
−
y
1
∗
m
1
=
a
1
x−y2∗m2=a2
x
−
y
2
∗
m
2
=
a
2
两个式子相减可以得到
y1∗m1−y2∗m2=a2−a1
y
1
∗
m
1
−
y
2
∗
m
2
=
a
2
−
a
1
然后这里
m1,m2,(a2−a1)
m
1
,
m
2
,
(
a
2
−
a
1
)
都是已知的
所以我们可以当一个不定方程来解
这样的话就是我们可以解出一个
y1
y
1
待回去就可以得到一个可能的
x0
x
0
但是这个
x0
x
0
并不是合法的
他仅仅满足下面这个式子
x=x0+k∗lcm(m1,m2)
x
=
x
0
+
k
∗
l
c
m
(
m
1
,
m
2
)
这个的话又可以看成一个新的同余方程
x≡x0(mod[m1,m2])
x
≡
x
0
(
m
o
d
[
m
1
,
m
2
]
)
然后如果满足这个方程就可以满足那两个方程了
然后就成功地吧两个方程合为一个
然后一直合下去
就可以得到一个唯一的不定方程
这个的话直接用扩展欧几里得来解就可以了
CODE:
#include<cstdio>
typedef long long LL;
LL exgcd (LL a,LL b,LL &x,LL &y)
{
if (a==0)
{
x=0;y=1;
return b;
}
LL tx,ty;
LL d=exgcd(b%a,a,tx,ty);
x=ty-(b/a)*tx;
y=tx;
return d;
}
int main()
{
LL n;
LL b1,m1;
bool tf=true;
scanf("%lld",&n);
scanf("%lld%lld",&b1,&m1);
for (LL u=2;u<=n;u++)
{
LL b2,m2;
scanf("%lld%lld",&b2,&m2);
LL A,B,x,y,dd=b2-b1;
A=m1,B=m2;
LL d=exgcd(A,B,x,y);
if (dd%d!=0) {printf("no solution!");return 0;}
x=(x*(dd/d)%(B/d)+(B/d))%(B/d);
b1=m1*x+b1;
m1=m1*m2/d;
}
if (tf==false) printf("no solution!");
else printf("%lld\n",b1);
return 0;
}