解题思路
可以先参考看看》》中国剩余定理(CRT )(跳过前面的铺垫直接看解法)
其实思路就是上面那个文章中的思路。首先,依题意得:
x
≡
b
i
(
m
o
d
a
i
)
x≡b_i(mod a_i)
x≡bi(modai)
而这样的方程有很多,自然变成一个同余方差组。
我们先举个解方程的例子,再带回题目中看:
再将问题进行分解,看
x
1
x_1
x1 如何求:
我们可以先求出 同余方程
x
x
1
≡
1
(
3
)
,
x
x
1
≡
0
(
5
)
,
x
x
1
≡
0
(
7
)
xx_1\equiv 1(3),xx_1\equiv 0( 5),xx_1\equiv 0( 7)
xx1≡1(3),xx1≡0(5),xx1≡0(7) 的解
x
x
1
xx_1
xx1
那么
x
1
=
2
∗
x
x
1
x_1=2*xx_1
x1=2∗xx1
求
x
x
1
xx_1
xx1:
因
x
x
1
≡
1
(
3
)
,
x
x
1
≡
0
(
5
)
,
x
x
1
≡
0
(
7
)
xx_1\equiv 1(3),xx_1\equiv 0( 5),xx_1\equiv 0( 7)
xx1≡1(3),xx1≡0(5),xx1≡0(7) 所以xx一定是 5和 7的公倍数,我们设
y
1
=
35
t
y_1=35t
y1=35t 那么现在就变成了
35
t
≡
1
(
3
)
35t\equiv 1(3)
35t≡1(3),可以转化成
35
t
−
1
=
3
k
35t-1=3k
35t−1=3k 再转化一下:
35
t
−
3
k
=
1
35t-3k=1
35t−3k=1。
这样就变成一个 e x g c d exgcd exgcd,扩欧求出t。
照这样求出所有的
x
x
,
x
=
2
∗
y
1
+
3
∗
y
2
+
2
∗
y
3
xx, x=2*y_1+3*y_2+2*y_3
xx,x=2∗y1+3∗y2+2∗y3
但是此时 x 还不是最小解, x 要不断减去
3
,
5
,
7
3,5,7
3,5,7 的最小公倍数直到不能减(==直接取模)
回到题目,把
x
≡
b
i
(
m
o
d
a
i
)
x≡b_i(mod a_i)
x≡bi(modai)转化为:
b
i
+
a
i
y
=
x
b_i+a_iy=x
bi+aiy=x ——>
x
−
a
i
y
=
b
i
x-a_iy=b_i
x−aiy=bi
WOW,和上面的方程如此相似,扩欧走起。。
(因为题目保证
a
i
a_i
ai 与
a
j
a_j
aj 互质,所以我们可以扩欧)
代码
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
int n;
ll a[100010],b[100010],maxn,ans;
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==0)
{
x=1,y=0;
return;
}
exgcd(b,a%b,x,y);
ll z=x;
x=y;
y=z-(a/b)*y;
}
int main() {
scanf("%d",&n);
maxn=1;
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&a[i],&b[i]);
maxn=maxn*a[i];
}
for(int i=1;i<=n;i++)
{
ll k=maxn/a[i];
ll x=0,y=0;
exgcd(k,a[i],x,y);
if(x<=0)x+=a[i];
ans=ans+x*k*b[i];
}
printf("%lld",ans%maxn);
}