求在小于等于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)。
Input
输入数据的第一行为一个正整数T,表示有T组测试数据。每组测试数据的第一行为两个正整数N,M (0 < N <= 1000,000,000 , 0 < M <= 10),表示X小于等于N,数组a和b中各有M个元素。接下来两行,每行各有M个正整数,分别为a和b中的元素。
Output
对应每一组输入,在独立一行中输出一个正整数,表示满足条件的X的个数。
Sample Input
3
10 3
1 2 3
0 1 2
100 7
3 4 5 6 7 8 9
1 2 3 4 5 6 7
10000 10
1 2 3 4 5 6 7 8 9 10
0 1 2 3 4 5 6 7 8 9
Sample Output
1
0
3
依然是套用中国剩余定理不互质情况下的模板
然后求出最小正整数解(注意必须要求最小正整数解)
根据通解形式
x=x0+k⋅lcm x = x 0 + k ⋅ l c m
只需要解不等式
x0+k⋅lcm≤N x 0 + k ⋅ l c m ≤ N
k≤N−x0lcm k ≤ N − x 0 l c m
即可,注意要判断 x0 x 0 必须是小于N的
code:
#include
#include
#include
using namespace std;
typedef long long ll;
bool flag;
ll m[100],a[100],lcm;
ll gcd(ll a,ll b){
return b ? gcd(b,a%b) : a;
}
ll ex_gcd(ll a,ll b,ll &x,ll &y){
if(!b){
x = 1;
y = 0;
return a;
}
ll g = ex_gcd(b,a%b,y,x);
y -= a / b * x;
return g;
}
ll China(ll n){
ll m1 = m[0],a1 = a[0];
ll m2,a2,k1,k2,x0,g,c;
lcm = m[0];
for(int i = 1; i < n; i++){
m2 = m[i];
a2 = a[i];
c = a2 - a1;
g = ex_gcd(m1,m2,k1,k2);
lcm = lcm * m[i] / gcd(lcm,m[i]);
if(c % g){
flag = false;
return 0;
}
x0 = k1 * c / g;
ll t = m2 / g;
x0 = (x0 % t + t) % t;
a1 += m1 * x0;
m1 = m2 / g * m1;
}
return a1;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
ll N;
int n;
scanf("%lld%d",&N,&n);
for(int i = 0; i < n; i++) scanf("%lld",&m[i]);
for(int i = 0; i < n; i++) scanf("%lld",&a[i]);
flag = true;
ll ans = China(n);
if(!flag || ans > N){
printf("0\n");
}
else{
if(ans <= 0) ans += lcm;
ans = (N - ans) / lcm + 1;
printf("%lld\n",ans);
}
}
return 0;
}