POJ2891 Strange Way to Express Integers 中国剩余定理(非互质) 数学专题第二题

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/86529903

题目P2101

http://poj.org/problem?id=2891

背景 Background
此系列问题为数论专题
具体参考博文
http://blog.csdn.net/chty2018/article/details/53432272
描述 Description
滑稽大师CDC找到了一种描述整数m的滑稽方法:
选n个数a1,a2,…,an,得到m%a1=r1,m%a2=r2,…,m%an=rn
现在已知a1,a2,…,an和r1,r2,…,rn,现在CDC想知道满足条件的最小的m是多少,以便他能在即将到来的滑稽大赛上装逼。
输入格式 Input Format
第一行一个整数n
接下来n行,每行2个整数:ai,ri
输出格式 Output Format
最小的m
若不存在,输出-1
样例输入 Sample Input
2
8 7
11 9
样例输出 Sample Output
31
时间限制 Time Limitation
1s
注释 Hint
1<=n<=20
1<=ai,ri<=100
来源 Source
【POJ2891】Strange Way to Express Integers 中国剩余定理(非互质)
题面数据来自宋逸群

题解

模板题。。。。。。。。。。。。。。和我之前找的模板不太一样,这个是非互质版的模板,那个是互质版的模板。

代码

//#include<bits/stdc++.h>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll maxn=1e5+10;
template<typename T>inline void read(T &x)
{
	x=0;
	static ll f=1;
	static char ch=getchar();
	while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); }
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x*=f;
}
ll n,a[maxn],r[maxn];
inline ll exgcd(ll a,ll b,ll &x,ll &y)
{
	if (!b)
	{
		x=1,y=0;
		return a;
	}
	ll ans=exgcd(b,a%b,x,y);
	ll tmp=x;
	x=y;
	y=tmp-a/b*y;
	return ans;
}
inline ll China()
{
	ll A=a[1],R=r[1],k,y;
	for (ll i=2;i<=n;++i)
	{
		ll gcd=exgcd(A,a[i],k,y),data=r[i]-R;
		if (data%gcd)
			return -1;
		ll tmp=a[i]/gcd;
		k*=data/gcd;
		k=(k%tmp+tmp)%tmp;
		R+=k*A;
		A=A*a[i]/gcd;
		R=(R+A)%A;
	}
	return R;
}
int main()
{
	while (~scanf("%lld",&n))
	{
		for (int i=1;i<=n;++i)
		{
			read(a[i]);
			read(r[i]);
		}
		printf("%lld\n",China());
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/86529903