【模板】合并模线性方程组(POJ2891)

Description

  给定(n)组同余关系,求解最小的非负整数(x),满足(x mod a_i = r_i)

Input

  第一行一个整数(n)
  接下来(n)行,每行两个整数,分别表示(a_i)(r_i)

Output

  一个正整数(x)即最小正整数解。若无解则输出(-1)

Solution

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
long long a[100010],r[100010],x,y;
long long exgcd(long long a,long long b,long long &x,long long &y)
{
	if (b==0)
	{
		x=1,y=0;
		return a;
	}
	long long p=exgcd(b,a%b,x,y);
	long long z=x;
	x=y,y=z-(a/b)*y;
	return p;
}
int main()
{
	while (scanf("%d",&n)!=EOF)
	{
		bool flag=1;
		for (int i=1;i<=n;i++)
			scanf("%lld%lld",&a[i],&r[i]);
		for (int i=1;i<n;i++)
		{
			x=0,y=0;
			long long d=exgcd(a[i],a[i+1],x,y),t=a[i+1]/d;
			if ((r[i+1]-r[i])%d) 
			{
				flag=0;
				break;
			}
			else
			{
				x=x*((r[i+1]-r[i])/d);
				x=(x%t+t)%t;
				r[i+1]=a[i]*x+r[i];
				a[i+1]=a[i]*a[i+1]/d;
				r[i+1]%=a[i+1];
			}
		}
		if (!flag) printf("-1
"); else printf("%lld
",r[n]);
	}
	return 0;
}

原文地址:https://www.cnblogs.com/Code-Geass/p/9933946.html