對於一個數x,知道:ios
x%m1=a1,x%m2=a2,x%m3=a3.(m1,m2,m3)互質。git
求x。spa
咱們來形象化一下:code
一個數,%3=1,%5=1,%7=2,這個數是什麼?blog
稍微試一試發現是16,那麼怎麼正常地算出來呢?get
咱們首先要弄明白一件事:string
若是a%b==c,那麼a加上一個b的倍數,%b仍是餘c。這個仍是很顯而易見的吧。it
那我咱們想要求出的x,能夠分爲三個數相加io
x=A1+A2+A3.其中A1%3=1,A2%5=1,A3%7=2.A二、3是3的倍數,A一、3是5的倍數,A一、2是7的倍數。class
咱們先求A3,A3要知足是五、3的倍數,也要知足%7=2,。
首先,咱們知道它必定是15的倍數,那麼咱們要知道怎樣才能知足%7=2
若是要求%7=2,只用求出來%7=1,而後再乘2就能夠了。
因而獲得了以下方程
15*t≡1(mod 7)
似曾相識,這個方程至關於15*t+7*y=1能夠用拓展歐幾里得求解。
而後,咱們知道t=1,也就是15*1%7=1,因此15*1*2%7就等於2.
因而A3就等於15*1*2=30,
以此類推,求出來A一、A2,最後加起來就是答案。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #define REP(i,k,n) for(LL i=k;i<=n;i++) #define in(a) a=read() using namespace std; typedef long long LL; inline LL read(){ LL x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x*f; } LL T; inline void exgcd(LL A,LL B,LL &x,LL &y){ if(B==0) x=1,y=0; else exgcd(B,A%B,x,y),T=x,x=y,y=T-A/B*y; } LL n,a[50],b[50],m[50],t[50]; LL M=1,ans; int main(){ in(n); REP(i,1,n) in(a[i]),in(b[i]),M=M*a[i]; REP(i,1,n){ m[i]=M/a[i]; LL x,y; exgcd(m[i],a[i],x,y); t[i]=x; ans=((ans+(b[i]*t[i]*m[i])%M+M)%M)%M; } cout<<ans; return 0; } /*3 3 1 5 1 7 2*/