#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int gcd(int a,int b){
if(b==0)
return a;
else{
while(int i=a%b){
a=b;
b=i;
}
return b;
}
}
int ex_gcd(int a,int b,int& x,int& y) {
if(b==0) {
x=1;
y=0;
return a;
}
int d=ex_gcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-a/b*y;
return d;
}
//解线性同余方程: ax+by=c
bool _LCE(int a, int b, int c, int &x, int &y) {
//printf("%d*x + %d*y = %d\n",a,b,c);
int x0,y0;
int d=ex_gcd(a,b,x0,y0);
if(c%d!=0){
//无解
return 0;
}
//ax0+by0=gcd(a,b)
int k=c/d;
x=x0*k;
y=y0*k;
//ax+by=c是一组解
//x'=x+bt,y'=y+at,是方程的所有解,对所有整数t成立
//printf("%d*%d + %d*%d = %d\n",a,x,b,y,c);
return 1;
}
//解线性同余方程 ax = b mod n
//这个是和 ax + ny mod b等价,注意变量
int LCE(int a,int b,int n){
//printf("%d*x = %d mod %d\n",a,b,n);
int x0,y0;
if(_LCE(a,n,b,x0,y0)){
int t=n/gcd(a,n);
//printf("gcd(%d,%d)=%d\n",a,n,gcd(a,n));
//printf("x0=%d,t=%d\n",x0,t);
//x=x0+k*(n/gcd(a,n)),对任意整数k都是解
//最小非负整数解
int x=(x0%t+t)%t;
//printf("%d*%d = %d mod %d\n",a,x,b,n);
return x;
}
else{
//无解
return -1;
}
}
int main() {
#ifdef Yinku
freopen("Yinku.in","r",stdin);
#endif // Yinku
int a,b;
while(~scanf("%d%d",&a,&b)) {
printf("%d\n",LCE(a,1,b));
}
return 0;
}
模板 - 扩展欧几里得算法
猜你喜欢
转载自www.cnblogs.com/Yinku/p/10969922.html
今日推荐
周排行