同余方程组解的个数 (hdu1573)

                        由此入门
  • 同余方程组(模非互质)可以通过合并方程求解。
  •         假设以上都知道的。或者点击打开链接
  • 通过以上方法求得最小正整数解x 方程组的模底为lcm=LCM(a1,a2...an) 
  •     通解:  
  •     有解:  
  •     无解:  
  • 注意:有解时,若a=0 则t=0去除,题目要求正整数。
#include<cstdio>
#define ll long long
int x,y;
int d;
int A[20];
int B[20];
void  exgcd(int a,int b){
	if(b==0){
		d=a;
		x=1;
		y=0;
		return ;
	}
	exgcd(b,a%b);
	int t=x;
	x=y;
	y=t-(a/b)*y;

}
int mod(int x,int n){
	return (x%n+n)%n;
	
}
//x=b[i](mod c[i])	
ll equation(int b[],int c[],int n){
	for(int i=1;i<n;i++){
		exgcd(c[i-1],c[i]);
		if((b[i]-b[i-1])%d)return -1;
		x=mod(x*(b[i]-b[i-1])/d,c[i]/d);
		b[i]=b[i-1]+x*c[i-1];
		c[i]=c[i-1]*c[i]/d;
	}
	return b[n-1];
}
int main(){
	int T;
	ll N,M;
	scanf("%d",&T);
	while(T--){
		scanf("%lld%lld",&N,&M);
		for(int i=0;i<M;i++)
			scanf("%d",&A[i]);
		for(int i=0;i<M;i++)
			scanf("%d",&B[i]);
		ll F=equation(B,A,M);
		if(F==-1||F>N)printf("0\n");
		else {
			//x+lcm*t<=N
			ll lcm=1;
			for(int i=0;i<M;i++){
				exgcd(lcm,A[i]);
				lcm=(lcm*A[i])/d;
			}
			if(F==0)printf("%lld\n",(N-F)/lcm);
			else printf("%lld\n",(N-F)/lcm+1);
			
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/kala0/article/details/79341123
今日推荐