在中国带孩子是一件非常痛苦的事(当然不包括可爱的妹子们呢)QAQ
然鹅,我们现在拥有一堆 孩子 方程
- \(x\equiv a_1mod(p_1)\)
\(x\equiv a_2mod(p_2)\)
\(…\)
\(x\equiv a_nmod(p_n)\)
且\(p_1,p_2…p_n 两两互质\),求最小的正整数x - 设M为\(p_1,p_2…p_n\)的积
设Mi为M/\(p_i=>M_i与p_i互质\)
设\(x_i\equiv1(modp_i),且x_i\equiv0(modM_i)=>x_i \equiv0 mod(p_{abcdefghj…}就是不等于i)\)
****也就是说\(x_i=k_iM_i\equiv1(mod)p_i\)然后我们可以通过求\(M_i\)的逆元\(k_i\)求得\(x_i\)**** - 根据同余定理
\(a_ix_i\equiv a_imod(p_i)\)
再根据同余定理
****则通解x为 \(\sum(a_ix_i)modM\)****
综****上****所诉x=((\(\sum(a_ik_iM_i)modM+M)mod M)\)
扩展
EXCRT
- \(x\equiv a_1mod(p_1)\)
\(x\equiv a_2mod(p_2)\)
\(…\)
\(x\equiv a_nmod(p_n)\)
且\(p_1,p_2…p_n 不一定互质\),求最小的正整数x
现在假设我们已知 \(x\equiv a_1mod(p_1),x\equiv a_2mod(p_2)\)
\(也就是说x=a_1+k_1p_1=a_2+k_2p_2\)
\(k_1p_1-k_2p_2=a_2-a_1\)用exgcd解出一组通解
因为x min 所以\(x_1\) min;
通过\(也就是说x=a_1+k_1p_1\)求出最小通解x'
合并成一个新的方程\(x≡x' \pmod {lcm(m1,m2))}\)
算法
考虑合并(发现的一个有意思的证明)
\(\left\{\begin{aligned}x\equiv B \pmod A\\x\equiv b_i\pmod {a_i}\\\end{aligned}\right.\)i
\(x=Am_1+B=a_im_2+b_ix=Am\therefore Am_1-a_im_2=b_i-B\)
由于bezoutbezout定理,
\(gcd(A,a_i)|(b-B)\)
否则无解。
\(设G=gcd(A,a_i)G=gcd(A,ai)\therefore A\frac {m_1G}{b_i-B}+a_i\frac {m_2G}{b_i-B}=G\)
设\(t_1=\frac {m_1G}{b_i-B},t_2=\frac {m_2G}{b_i-B} \therefore At_1+a_it_2=G\)
\(用exgcd解出一组特解t_x,t_y\)
根据不定方程特解公式:
\(t_1=t_x+d\frac {a_i}{G}\)
\(m_1=(t_x+d\frac {a_i}{G})\frac {b_i-B}{G}\)
\(x=A(t_x+d\frac {a_i}{G})\frac {b_i-B}{G}+B\)
\(x=At_x\frac {b_i-B}{G}+d\cdot A\frac {a_i}{gcd(a_i,A)}\frac {b_i-B}{G}+B\)
\(x=At_x\frac {b_i-B}{G}+d\cdot lcm(A,a_i)\frac {b_i-B}{G}+B\)
显然d=0解最小,所以原方程最小解
\(x=At_x\frac {b_i-B}{G}+B\)
合并之后的通解就是
\(x\equiv At_x\frac {b_i-B}{G}+B \pmod {lcm(A,a_i)}\)
#include<bits/stdc++.h>
#define re return
#define inc(i,l,r) for(int i=l;i<=r;++i)
const int maxn=1e5+5;
typedef long long ll;
template<typename T>inline void rd(T&x)
{
char c;bool f=0;
while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
x=c^48;
while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
if(f)x=-x;
}
using namespace std;
int n;
ll ans,LCM,x,y,a[maxn],b[maxn];
ll EXGCD(ll a,ll b,ll &x,ll&y)
{
if(!b){x=1;y=0;re a;}
ll d=EXGCD(b,a%b,x,y);
ll z=x;
x=y;
y=z-(a/b)*y;
re d;
}
ll vivi(ll k,ll n,ll mod)
{
ll ans=0;
while(n)
{
if(n&1)ans=(ans+k)%mod;
n>>=1;
k=(k+k)%mod;
}
re ans;
}
int main()
{
// freopen("vv.txt","r",stdin);
rd(n);
inc(i,1,n)
rd(b[i]),rd(a[i]);
ans=a[1];
LCM=b[1];
inc(i,2,n)
{
ll B=((a[i]-ans)%b[i]+b[i])%b[i];
//k1*p1-k2*p2=a2-a1=d
ll gcd=EXGCD(LCM,b[i],x,y);
x=vivi(x,B/gcd,b[i]);
//x1=k1*(d/g)
ans+=LCM*x;
//x=a1+k1*p1
LCM*=b[i]/gcd;
ans=(ans+LCM)%LCM;
}
printf("%lld\n",ans);
re 0;
}