由已知:
{
(
n
−
a
1
)
∣
b
1
(
n
−
a
2
)
∣
b
2
.
.
.
.
.
.
(
n
−
a
k
)
∣
b
k
\begin{cases} (n-a_1)\ |\ b_1\\ (n-a_2)\ |\ b_2\\ ...\ ...\\ (n-a_k)\ |\ b_k\\ \end{cases}
⎩⎪⎪⎪⎨⎪⎪⎪⎧(n−a1) ∣ b1(n−a2) ∣ b2... ...(n−ak) ∣ bk
变换一下:
{
n
−
a
1
≡
0
(
m
o
d
b
1
)
n
−
a
2
≡
0
(
m
o
d
b
2
)
.
.
.
.
.
.
n
−
a
k
≡
0
(
m
o
d
b
k
)
\begin{cases} n-a_1≡\ 0\ (mod\ \ b_1)\\ n-a_2≡\ 0\ (mod\ \ b_2)\\ ...\ ...\\ n-a_k≡\ 0\ (mod\ \ b_k)\\ \end{cases}
⎩⎪⎪⎪⎨⎪⎪⎪⎧n−a1≡ 0 (mod b1)n−a2≡ 0 (mod b2)... ...n−ak≡ 0 (mod bk)
再变换一下:
{
n
≡
a
1
(
m
o
d
b
1
)
n
≡
a
2
(
m
o
d
b
2
)
.
.
.
.
.
.
n
≡
a
k
(
m
o
d
b
k
)
\begin{cases} n≡\ a_1\ (mod\ \ b_1)\\ n≡\ a_2\ (mod\ \ b_2)\\ ...\ ...\\ n≡\ a_k\ (mod\ \ b_k)\\ \end{cases}
⎩⎪⎪⎪⎨⎪⎪⎪⎧n≡ a1 (mod b1)n≡ a2 (mod b2)... ...n≡ ak (mod bk)
然后就直接上
c
r
t
crt
crt模板,但是这道题有几个地方要注意:
1.
1.
1.输入的
a
[
i
]
a[i]
a[i]可能为负
2.
2.
2.中间计算结果的时候可能会包
l
o
n
g
l
o
n
g
long \ \ long
long long,中间要用快速乘。
O ( 1 ) O(1) O(1)快速乘模板:
inline ll mul(ll x,ll y,ll mod) {
x%=mod,y%=mod;
ll z=(long double)x*y/mod,ans=x*y-z*mod;
if(ans<0) ans+=mod;
else if(ans>=mod) ans-=mod;
return ans;
}
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define repl(i,x,y) for(ll i=(x);i<(y);i++)
#define repd(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;
const ll N=1e4+5;
const ll Inf=1e18;
ll k,n,a[N],b[N];
inline ll add(ll x,ll y,ll mod) {
return x+y>=mod?x+y-mod:x+y;
}
inline ll mul(ll x,ll y,ll mod) {
x%=mod,y%=mod;
ll z=(long double)x*y/mod,ans=x*y-z*mod;
if(ans<0) ans+=mod;
else if(ans>=mod) ans-=mod;
return ans;
}
void exgcd(ll a,ll b,ll &x,ll &y) {
if(!b) {
x=1,y=0;return ;
}exgcd(b,a%b,x,y);
ll ret=x;x=y;y=ret-a/b*y;
}
void china() {
ll bb=1;
rep(i,1,k) bb*=b[i];
rep(i,1,k) {
ll x,y,bi=bb/b[i];
exgcd(bi,b[i],x,y);
x=(x%b[i]+b[i])%b[i];
n=(n+mul(mul(x,bi,bb),a[i],bb))%bb;
}
n=(n+bb)%bb;
}
int main() {
scanf("%lld",&k);
rep(i,1,k) scanf("%lld",&a[i]);
rep(i,1,k) scanf("%lld",&b[i]);
rep(i,1,k) a[i]=(a[i]%b[i]+b[i])%b[i];
china();
printf("%lld\n",n);
return 0;
}