CRT【p3868】[TJOI2009]猜數字
阿新 • • 發佈:2018-11-08
Description
現有兩組數字,每組k個,第一組中的數字分別為:a1,a2,...,ak表示,第二組中的數字分別用b1,b2,...,bk表示。其中第二組中的數字是兩兩互素的。求最小的非負整數n,滿足對於任意的i,n - ai能被bi整除。
Input
輸入資料的第一行是一個整數k,(1 ≤ k ≤ 10)。接下來有兩行,第一行是:a1,a2,...,ak,第二行是b1,b2,...,bk
Output
輸出所求的整數n。
\(CRT\)。
通過讀題,我們可以得到一群這樣的關係
\[ n-a_i \equiv 0(mod \ b_i) \]
然後移項
\[ n \equiv a_i(mod \ b_i) \]
\(What's \ this?\)中國剩餘定理。
懶得在這推了,所以就是裸的\(CRT\)問題了。
放下程式碼好了。
程式碼
#include<cstdio> #include<iostream> #include<algorithm> #define int long long #define R register using namespace std; const int gz=18; inline void in(R int &x) { R int f=1;x=0;char s=getchar(); while(!isdigit(s)){if(s=='-')f=-1;s=getchar();} while(isdigit(s)){x=x*10+s-'0';s=getchar();} x*=f; } int a[gz],b[gz],N=1,n,ans; int exgcd(R int a,R int b,R int &x,R int &y) { if(b==0) { x=1;y=0; return a; } R int t=exgcd(b,a%b,x,y); R int tmp=x; x=y;y=tmp-a/b*y; return t; } inline int mul(R int x,R int y) { R int res=0; for(;y;y>>=1,x=(x+x)%N) if(y&1)res=(res+x)%N; return res; } inline void China() { for(R int i=1;i<=n;i++) { R int bb=N/b[i]; R int aa=b[i]; R int x,y; exgcd(aa,bb,x,y); (y+=b[i])%=b[i]; R int tmp=mul(bb,y)%N; (ans+=mul(a[i],tmp)%N)%=N; } } signed main() { in(n); for(R int i=1;i<=n;i++)in(a[i]); for(R int i=1;i<=n;i++)in(b[i]),N*=b[i]; China(); printf("%lld",(ans+N)%N); }