利用模板求出最小解,如果最小解大于n或者无最小解(此模板返回-1),则无解
否则输出(n-ans)/dg+1(dg为a[i]的最小公倍数,ans为最小解),所有满足dg*i+ans的都符合要求,ans为最小的满足的数
#include<stdio.h>
using namespace std;
#define ll long long
ll A[11],B[11];//B[i]为余数
ll dg,ans;//dg为A[i]的最小公倍数 ans 为最小解
void exgcd(ll a, ll b, ll &d, ll&x, ll &y)
{
if (!b) {d=a; x=1; y=0;}
else
{
exgcd(b, a%b, d, y, x);
y-=x*(a/b);
}
}
ll gcd(ll a, ll b)
{
if (!b) return a;
else gcd(b, a%b);
}
ll china(ll n)
{
ll a,b,d,x,y,dm;
ll c,c1,c2;
a=A[0]; c1=B[0];
for (int i=1; i<n; i++)
{
b=A[i]; c2=B[i];
exgcd(a, b, d, x, y);
dm=b/d;
c=c2-c1;
if (c%d) return -1;
x=((x*c/d)%dm+dm)%dm;//x可能为负
c1=a*x+c1;
a=a*b/d;
}
dg=a;//dg是最大公约数
if (!c1)//考虑c1为0的情况
{
c1=1;
for (int i=0; i<n; i++)
{
c1=c1*A[i]/gcd(c1, A[i]);
}
dg=c1;//此时dg为最小公倍数
}
return c1;//c1为最小的X
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
scanf("%lld",&A[i]);
for(int i=0;i<m;i++)
scanf("%lld",&B[i]);
ans=china(m);
if(ans==-1||ans>n)
printf("0\n");
else printf("%d\n",(n-ans)/dg+1);
}
return 0;
}