题意:求在小于等于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)。
思路:运用我上一个博客的模板再加一个 性质—— 通解:X=X'+lcm(a[0],a[1]..a[i])*k (其中X'是该线性同余方程的最小非负整数解,k=0,1,2,3...),那么:ans = (N-X')/lcm+1,(ps:加1是因为k是从0开始的)注意当X'=0时 X=lcm*k(k=0,1,2..),由于题目要求小于等于N的正整数中有多少个X,这时ans = N/lcm;
代码:
#include <iostream> #include <cstdio> #define ll long long using namespace std; ll gcd(ll a,ll b) { if(b==0) return a; else return gcd(b,a%b); } ll lcm(ll a,ll b) { return a*b/gcd(a,b); } ll exgcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1; y=0; return a; } ll d=exgcd(b,a%b,x,y); ll t=x; x=y; y=t-a/b*y; return d; } ll solve(ll a[],ll r[],ll n) { ll d,c,i,x,y,t; for(i=1;i<n;i++) { c=r[i]-r[i-1]; d=exgcd(a[i-1],a[i],x,y); if(c%d!=0) return -1; t=a[i]/d; x=(x*(c/d)%t+t)%t; r[i]=a[i-1]*x+r[i-1]; a[i]=a[i-1]*(a[i]/d); } return r[n-1]; } int main() { int t; ll a[15]; ll r[15]; cin>>t; while(t--) { ll N,M; ll lcmm; scanf("%lld %lld",&N,&M); for(int i=0;i<M;i++) { scanf("%lld",&a[i]); if(i==0) lcmm=a[i]; else lcmm=lcm(a[i],lcmm); } for(int i=0;i<M;i++) { scanf("%lld",&r[i]); } ll minn=solve(a,r,M); ll ans; if(minn==-1||minn>N) cout<<"0"<<endl; else { ans = (N-minn)/lcmm+1; if(minn==0) ans = N/lcmm; cout<<ans<<endl; } } return 0; }