hdu 1573 X问题 (exgcd求解一般线性同余方程组解的个数)

题目链接

题意:求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], …, X mod a[i] = b[i], … (0 < a[i] <= 10)。

思路:先用扩展欧几里得算法(excrt)解一般同余方程求出一个特解R,然后通解R' = R + k * LCM(a1..am)

注意一些特殊情况,如果无解输出0,如果n小于最小的正整数的R也输出0,

否则答案为(n-R)/M + 1

 1/* ***********************************************
 2Author :111qqz
 3Created Time :Sat 15 Oct 2016 03:31:09 PM CST
 4File Name :code/hdu/1573.cpp
 5************************************************ */
 6#include <cstdio>
 7#include <cstring>
 8#include <iostream>
 9#include <algorithm>
10#include <vector>
11#include <queue>
12#include <set>
13#include <map>
14#include <string>
15#include <cmath>
16#include <cstdlib>
17#include <ctime>
18#define fst first
19#define sec second
20#define lson l,m,rt<<1
21#define rson m+1,r,rt<<1|1
22#define ms(a,x) memset(a,x,sizeof(a))
23typedef long long LL;
24#define pi pair < int ,int >
25#define MP make_pair
26using namespace std;
27const double eps = 1E-8;
28const int dx4[4]={1,0,0,-1};
29const int dy4[4]={0,-1,1,0};
30const int inf = 0x3f3f3f3f;
31const int N =15;
32LL a[N],r[N];
33LL nn;
34int m;
35LL exgcd(LL a,LL b,LL &x,LL &y)
36{
37    if (b==0)
38    {
39	x = 1;
40	y = 0 ;
41	return a;
42    }
43    LL ret = exgcd( b, a%b,y,x);
44    y-=x*(a/b);
45    return ret;
46}
47LL ex_crt(LL *m,LL *r,int n)
48{
49     LL M = m[1] , R = r[1],x,y,gcd;
50     for ( int i = 2 ; i <= n ; i++)
51	{
52	    gcd = exgcd(M,m[i],x,y);
53	    if ((r[i]-R)%gcd) return 0;
54	    LL gx = m[i]/gcd;
55	    x = x*(r[i]-R)/gcd;
56	    x %=gx;
57	    R += x*M;
58	    M = M / gcd * m[i];
59	    R%=M;
60	}
61     if (R<=0) R+=M;
62     if (nn<R) return 0;
63     return (nn-R)/M + 1;
64}
65int main()
66{
67	#ifndef  ONLINE_JUDGE 
68	freopen("code/in.txt","r",stdin);
69  #endif
70	int T;
71	cin>>T;
72	while (T--)
73	{
74	    scanf("%lld %d",&nn,&m);
75	    for ( int i = 1 ; i <= m ; i++) scanf("%lld",&a[i]);
76	    for ( int i = 1 ; i <= m ; i++) scanf("%lld",&r[i]);
77	    LL res = ex_crt(a,r,m);
78	    printf("%lld\n",res);
79	}
80  #ifndef ONLINE_JUDGE  
81  fclose(stdin);
82  #endif
83    return 0;
84}