hdu 1573(中国剩余定理非互质情况)

解题思路:这道题目有可能a[i],两两不互质,所以直接用中国剩余定理肯定是不对的。。这里考虑非互质的情况

ee09991f-0311-31c0-986f-a838796b7646.png (141×100)

问题描述:给出bi,ni的值,且n1, n2, n3,…, ni两两之间不一定互质,求Res的值? 
解:采用的是合并方程的做法。 
这里将以合并第一第二个方程为例进行说明
 
由上图前2个方程得(设k1、k2为某一整数):
 

hdu 1573(中国剩余定理非互质情况)_第1张图片

hdu 1573(中国剩余定理非互质情况)_第2张图片

这里实际上是利用了一种迭代的思想,前两个方程合并成一个新的模方程,然后再与第三个合并.......,一直到最后一个方程,最后可以求出解来。。注意这里为了求出最小非负整数解,采用了很多技巧。。


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int gcd(int a,int b,int &x,int &y)
{
	if(a == 0 && b == 0) return -1;
	if(b == 0)
	{
		x = 1;
		y = 0;
		return a;
	}
	int d = gcd(b,a%b,y,x);
	y -= a/b*x;
	return d;
}

int main()
{
	int n,m,t,m1,m2,r1,r2,flag;
	int a[11],b[11];
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		for(int i = 0; i < m; i++)
			cin>>a[i];
		for(int i = 0; i < m; i++)
			cin>>b[i];
		flag = 0; m1 = a[0]; r1 = b[0];
		for(int i = 1; i < m; i++)
		{
			int x,y;
			m2 = a[i]; r2 = b[i];
			int d = gcd(m1,m2,x,y);
			int c = r2-r1;
			if(c % d)
			{
				flag = 1;
				break;
			}
			int tmp = m2 / d;
			x = (c / d * x % tmp + tmp) % tmp;
			r1 = r1 + x * m1;
			m1 = m1 / d * m2;
		}
		if(flag || n < r1) 
			cout<<0<<endl;
		else
		{
			int ans = (n - r1) / m1 + 1;  //m1为ai的最小公倍数,凡是m1*i+r1的都是符合要求的数,其中r1最小  
			if(r1 == 0) ans--;        //要求是正整数  
			cout<<ans<<endl;
		}
	}
	return 0;
}


你可能感兴趣的:(数学)