2017.10.6 国庆清北 D6T2 同余方程组
题目描述
求关于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 }