1. 程式人生 > >2017.10.6 國慶清北 D6T2 同余方程組

2017.10.6 國慶清北 D6T2 同余方程組

技術 erl ber 滿足 iostream 方程組 hide main word

題目描述

求關於x 的同余方程組

x%a1 = b1
x%a2 = b2
x%a3 = b3
x%a4 = b4
的大於等於0 的最小整數解。

輸入輸出格式

輸入格式:

一行8 個整數,表示a1; b1; a2; b2; a3; b3; a4; b4。

輸出格式:

一行一個整數,答案除以p 的余數。

輸入輸出樣例

輸入樣例#1:
2 0 3 1 5 0 7 3
輸出樣例#1:
10

說明

對於30% 的數據,ai <=40, 保證ai 均為素數。

對於60% 的數據,1 <=ai <=10^3, 保證ai 均互素。

對於100% 的數據,0 <= bi < ai; 1 <=ai <= 10^3。

技術分享
 1 /*
 2 其實這是一個滿分暴力(其實也不太算暴力,用的大數翻倍法)。
 3 
 4 c%a1=b1 --> (c-b1)%a1=0 
 5 c%a2=b2 --> (c-b2)%a2=0 
 6 c%a3=b3 --> (c-b3)%a3=0 
 7 c%a4=b4 --> (c-b4)%a4=0 
 8 設c=b1,此時c滿足c%a1=b1,讓c累加a1,使c滿足c%a2=b2,然後我們讓c+=lcm(a1,a2),使c%a3=b3,此時c仍然滿足c%a1=b1 && c%a2=b2 
 9 再讓c+=lcm(a1,a2,a3),使c滿足c%a4=b4,則此時c同時滿足了四個條件。 
10 為什麽呢,因為c加的是倍數,所以mod一下相當於不變,這樣c%那個a後還是那個b。 11 */ 12 #include<iostream> 13 #include<cstdio> 14 #include<cstring> 15 #include<cmath> 16 #include<algorithm> 17 using namespace std; 18 19 long long ans; 20 int a[5],b[5]; 21 int lcm1,lcm2; 22 23 inline void read(int &num)
24 { 25 char c=getchar(); 26 for(;!isdigit(c);c=getchar()); 27 for(;isdigit(c);c=getchar()){num=num*10+c-0;} 28 } 29 30 int gcd(int a,int b) 31 { 32 return b?gcd(b,a%b):a; 33 } 34 35 inline void init() 36 { 37 for(int i=1;i<=4;i++) 38 read(a[i]),read(b[i]); 39 ans=b[1]; 40 lcm1=a[1]*a[2]/gcd(a[1],a[2]); 41 lcm2=lcm1*a[3]/gcd(lcm1,a[3]); 42 while(ans%a[2]!=b[2]) ans+=a[1]; //找ans使ans滿足c%a1=b1 && c%a2=b2 43 while(ans%a[3]!=b[3]) ans+=lcm1; //找ans使ans滿足c%a1=b1 && c%a2=b2 && c%a3=b3 44 while(ans%a[4]!=b[4]) ans+=lcm2; //找ans使ans滿足c%a1=b1 && c%a2=b2 && c%a3=b3 && c%a4=b4 45 printf("%lld",ans); 46 } 47 48 int main() 49 { 50 //freopen("mod.in","r",stdin); 51 //freopen("mod.out","w",stdout); 52 init(); 53 fclose(stdin);fclose(stdout); 54 return 0; 55 }
View Code

2017.10.6 國慶清北 D6T2 同余方程組