求最大公约数 的方法:欧几里得算法 也就是 gcd 不多说 ,但是只适用于一对数字
而多对的话,就需要exgcd,
/* ax+by =c ; */ ll exgcd(ll a,ll b,ll &x,ll &y){ if(b==0) { x=1; y=0; return a; } ll r=exgcd(b,a%b,x,y); ll t=x; x=y; y=t-a/b*y; return r; }例题: 链接: https://www.nowcoder.net/acm/contest/75/B
来源:牛客网
题目描述
uu遇到了一个小问题,可是他不想答。你能替他解决这个问题吗?
问题:给你k对a和r是否存在一个正整数x使每队a和r都满足:x mod a=r,求最小正解x或无解。
问题:给你k对a和r是否存在一个正整数x使每队a和r都满足:x mod a=r,求最小正解x或无解。
输入描述:
第一行是正整数k(k<=100000) 接下来k行,每行有俩个正整数a,r(100000>a>r>=0)
输出描述:
在每个测试用例输出非负整数m,占一行。 如果有多个可能的值,输出最小的值。 如果没有可能的值,则输出-1。
示例1
输入
2 8 7 11 9
输出
31
#include<iostream> #define ll long long using namespace std; ll a[100025],b[100025]; ll k; ll exgcd(ll a,ll b,ll &x,ll &y){ if(b==0) { x=1; y=0; return a; } ll r=exgcd(b,a%b,x,y); ll t=x; x=y; y=t-a/b*y; return r; } ll Chinese_Remainder(){ ll m1,r1,m2,r2,flag,i,d,x,y,c,t; m1=a[0],r1=b[0]; flag=0; for(i=1;i<k;i++) { m2=a[i],r2=b[i]; if(flag) continue; d=exgcd(m1,m2,x,y); c=r2-r1; if(c%d) { flag=1; break; } t=m2/d; x=(c/d*x%t+t)%t; r1=m1*x+r1; m1=m1*m2/d; } if(flag) return -1; if(k==1&&r1==0) return m1; return r1; } int main(){ cin>>k; for(ll i=0;i<k;i++) cin>>a[i]>>b[i]; cout<<Chinese_Remainder()<<endl; return 0; }
未来的我一定会感谢正在努力的现在的我!