hdu1573:数论,线性同余方程组
题目大意:
给定一个N ,m
找到小于N的 对于i=1....m,满足 x mod ai=bi 的 x 的数量。
分析
先求出 同余方程组 的最小解x0,然后 每增加lcm(a1...,am)都会存在一个解,注意必须小于N 不能等于
代码:
#include <iostream> #include <stdio.h> #include<string.h> #include<algorithm> #include<string> #include<ctype.h> using namespace std; #define MAXN 10000 int a[11]; int b[11]; int n,m; int gcd(int a,int b) { return b?gcd(b,a%b):a; } int lcm(int a,int b) { return a*b/(gcd(a,b)); } int exgcd(int a,int b,int &x,int &y) { if(!b) { x=1; y=0; return a; } int tt=exgcd(b,a%b,x,y); int t; t=x; x=y; y=(t-a/b*y); return tt; } int solve() { int a1,a2,b1,b2,x,y,A,B,C,d,t; a1=a[0]; b1=b[0]; for(int i=1;i<m;i++) { a2=a[i]; b2=b[i]; A=a1; B=a2; C=b2-b1; d=exgcd(A,B,x,y); if(C%d) { return -1; } t=B/d; x=(x*(C/d)%t+t)%t; b1=a1*x+b1; a1=a1/d*a2; } return b1; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { scanf("%d",a+i); } for(int i=0;i<m;i++) { scanf("%d",b+i); } int lm=1; for(int i=0;i<m;i++) { lm=lcm(a[i],lm); } int ans=0; int tmp=solve(); if(tmp==-1) { puts("0"); continue; } if(tmp<=n) ans+=1+(n-tmp)/lm; if(ans&&tmp==0) ans--; cout<<ans<<endl; } return 0; }