版权声明: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;
}