非互素中国剩余定理解法

校赛学长出的一道题~

Last week, YaoBIG bought n lights from a shopping mall and he hoped to lighten all of them. Unfor-
tunately, there was something wrong with the lights. For the ith light, it just shone at the first ai minute
and re-shone every bi minutes. (This means: Except for the minutes ai, ai +bi, ai +2bi,..., the ith light
went out.)
YaoBIG just wanted to know if there was a time that all lights shone together?

Input
The input contains zero or more test cases and the first line of the input gives the number T of test
cases. For each test case:
The first line contains an integer n which represents the amount of the lights.
For the next n lines, there are two integers ai and bi in the ith line.
Output
For each test case, output the minimum time t when all lights shone together. If the time doesn’t
exist, just output -11.
Limits
0 <=T <=1 000
1 <=n<=300
0 <=ai <=bi<=16

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<bits/stdc++.h>
 4 #define rep(i,a,b) for(int i=a;i<=b;++i)
 5 typedef long long ll;
 6 const int MAXN=310;
 7 int a[MAXN];int b[MAXN];
 8 using namespace std;
 9 ll extend_gcd(ll a,ll b,ll &x,ll &y)    //扩展欧几里得算法,求gcd的同时递归修改x,y,最终满足xa+yb=gcd(a,b)
10 {
11     if(b==0)
12     {
13         x=1;y=0;return a;
14     }
15         ll r=extend_gcd(b,a%b,x,y);
16         ll tmp=x;
17         x=y;y=tmp-(a/b)*y;
18         return r;
19 }
20 class node
21 {
22    public:
23     ll a,b;
24     node(ll x=0,ll y=0):a(x),b(y){}
25     node operator +(const node &A)const
26     {
27         if(b==0||A.b==0) return node(0,0);      //代表前面的方程组已经无解
28         ll x,y;
29         ll gcd=extend_gcd(b,A.b,x,y);
30         if((a-A.a)%gcd!=0) return node(0,0);    //条件不满足则无解
31         ll newb=b*A.b/gcd,newa=newb;            //核心部分,具体请看前面写的证明
32         x=(x*(A.a-a)*b/gcd)%newb;
33         x=(x+newb)%newb;
34         newa=(a+x)%newb;
35         return node(newa,newb);
36     }
37 
38 };
39  int main()
40  {
41     // freopen("in.txt","r",stdin);
42      int T;
43      scanf("%d",&T);
44      rep(k,1,T)
45      {
46          int n;scanf("%d",&n);
47          rep(i,1,n) scanf("%d%d",&a[i],&b[i]);
48          node tmp=node(0,1);
49          rep(i,1,n) tmp=tmp+node(a[i],b[i]);
50          printf("%lld
",tmp.b==0?-1:tmp.a);
51      }
52      return 0;
53  }
原文地址:https://www.cnblogs.com/zhixingr/p/6748341.html