学习博客
(博主讲的很好
gcd
int gcd(ll a,ll b)
{
a = abs(a),b = abs(b);
while (b) {
int c = b;
b = a % b;
a = c;
}
return a;
}
证明:
设
r
=
a
%
b
,
c
=
g
c
d
(
a
,
b
)
r=a\%b,c=gcd(a,b)
r=a%b,c=gcd(a,b)
则
a
=
x
c
,
b
=
y
c
a=xc,b=yc
a=xc,b=yc,其中
x
,
y
x,y
x,y 互质
r
=
a
%
b
=
a
−
p
b
=
x
c
−
p
y
c
=
(
x
−
p
y
)
c
r=a\%b=a-pb=xc-pyc=(x-py)c
r=a%b=a−pb=xc−pyc=(x−py)c
又
b
=
y
c
b=yc
b=yc
所以
y
y
y 与
x
−
p
y
x-py
x−py 互质
\quad
证明:
假设
y
y
y 与
x
−
p
y
x-py
x−py 不互质
设
y
=
n
k
,
x
−
p
y
=
m
k
y=nk , x-py=mk
y=nk,x−py=mk , 且
k
>
1
k>1
k>1 (因为不互质)
将
y
y
y 带入可得
x
−
p
n
k
=
m
k
x-pnk=mk
x−pnk=mk
x
=
(
p
n
+
m
)
k
x=(pn+m)k
x=(pn+m)k
则
a
=
x
c
=
(
p
n
+
m
)
k
c
,
b
=
y
c
=
n
k
c
a=xc=(pn+m)kc , b=yc=nkc
a=xc=(pn+m)kc,b=yc=nkc
那么此时
a
a
a 与
b
b
b 的最大公约数为
k
c
kc
kc 不为
c
c
c
与原命题矛盾,因此
k
=
1
k=1
k=1,
y
y
y 与
x
−
p
y
x-py
x−py 互质
所以
r
r
r 与
b
b
b 的最大公约数为
c
c
c
即
g
c
d
(
b
,
r
)
=
c
=
g
c
d
(
a
,
b
)
gcd(b,r)=c=gcd(a,b)
gcd(b,r)=c=gcd(a,b)
GCD 与 LCM 的一些性质与定理
- g c d ( F ( n ) , F ( m ) ) = F ( g c d ( n , m ) ) F 为 斐 波 那 契 数 列 gcd(F(n),F(m))=F(gcd(n,m)) \ F为斐波那契数列 gcd(F(n),F(m))=F(gcd(n,m)) F为斐波那契数列
- g c d ( a m − 1 , a n − 1 ) = a g c d ( n , m ) − 1 ( a > 1 , n > 0 , m > 0 ) gcd(a^m-1,a^n-1)=a^{gcd(n,m)}-1(a>1,n>0,m>0) gcd(am−1,an−1)=agcd(n,m)−1(a>1,n>0,m>0)
- g c d ( a m − b m , a n − b n ) = a g c d ( n , m ) − b g c d ( n , m ) ( g c d ( a , b ) = 1 ) gcd(a^m-b^m,a^n-b^n)=a^{gcd(n,m)}-b^{gcd(n,m)}(gcd(a,b)=1) gcd(am−bm,an−bn)=agcd(n,m)−bgcd(n,m)(gcd(a,b)=1)
- g c d ( a , b ) = g c d ( a m , b n ) gcd(a,b)=gcd(a^m,b^n) gcd(a,b)=gcd(am,bn)
- a ∗ b % ( a + b ) = 0 ⟹ g c d ( a , b ) ! = 1 a*b\%(a+b)=0 \Longrightarrow gcd(a,b)!=1 a∗b%(a+b)=0⟹gcd(a,b)!=1
- 设 G = g c d ( G n 1 , G n 2 , . . . , G n n − 1 ) 设G=gcd(G_n^1,G_n^2,...,G_n^{n-1}) 设G=gcd(Gn1,Gn2,...,Gnn−1)
- n n n 为素数, G = n G=n G=n
- n n n 为非素数且由一个素因子 p p p, G = p G=p G=p
- n n n 有多个素因子, G = 1 G=1 G=1
- ( n + 1 ) l c m ( C n 0 , C n 1 , . . . , C n n ) = l c m ( 1 , 2 , . . . , n + 1 ) (n+1)lcm(C_n^0,C_n^1,...,C_n^n)=lcm(1,2,...,n+1) (n+1)lcm(Cn0,Cn1,...,Cnn)=lcm(1,2,...,n+1)
exgcd
扩展欧几里得算法,简称 exgcd,一般用来求解不定方程,求解线性同余方程,求解模的逆元等
裴蜀定理:对于两个不全为 0 0 0 的整数 a 、 b a、b a、b,方程 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b) 至少存在一组解 x , y x,y x,y。
证明:设
a
>
b
a>b
a>b
1,显然当
b
=
0
,
g
c
d
(
a
,
b
)
=
a
b=0,gcd(a,b)= a
b=0,gcd(a,b)=a。此时
x
=
1
,
y
=
0
x=1,y=0
x=1,y=0
2,
a
b
!
=
0
ab!=0
ab!=0 时
设
a
x
1
+
b
y
1
=
g
c
d
(
a
,
b
)
ax1+by1=gcd(a,b)
ax1+by1=gcd(a,b)
b
x
2
+
(
a
%
b
)
y
2
=
g
c
d
(
b
,
a
%
b
)
bx2+(a \% b)y2=gcd(b,a \% b)
bx2+(a%b)y2=gcd(b,a%b)
根据朴素的欧几里德原理有
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
%
b
)
gcd(a,b)=gcd(b,a \%b)
gcd(a,b)=gcd(b,a%b);
则:
a
x
1
+
b
y
1
=
b
x
2
+
(
a
%
b
)
y
2
ax1+by1=bx2+(a \% b)y2
ax1+by1=bx2+(a%b)y2
即:
a
x
1
+
b
y
1
=
b
x
2
+
(
a
−
(
a
/
b
)
∗
b
)
y
2
=
a
y
2
+
b
x
2
−
(
a
/
b
)
∗
b
y
2
ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2
ax1+by1=bx2+(a−(a/b)∗b)y2=ay2+bx2−(a/b)∗by2
根据恒等定理得:
x
1
=
y
2
;
y
1
=
x
2
−
(
a
/
b
)
∗
y
2
x1=y2; y1=x2-(a/b)*y2
x1=y2;y1=x2−(a/b)∗y2
这样我们就得到了求解
x
1
,
y
1
x1,y1
x1,y1 的方法:
x
1
,
y
1
x1,y1
x1,y1 的值基于
x
2
,
y
2
x2,y2
x2,y2
上面的思想是以递归定义的,因为
g
c
d
gcd
gcd 不断的递归求解一定会有个时候
b
=
0
b=0
b=0,所以递归可以结束。
最后
r
e
t
u
r
n
return
return 的是
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b)
code:
//递归代码
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, y, x);
y -= a / b * x;
return r;
}
// 非递归算法
ll exgcd(ll m, ll n, ll &x, ll &y) {
ll x1, y1, x0, y0;
x0 = 1; y0 = 0;
x1 = 0; y1 = 1;
x = 0; y = 1;
ll r = m % n;
ll q = (m - r) / n;
while(r) {
x = x0 - q * x1;
y = y0 - q * y1;
x0 = x1; y0 = y1;
x1 = x; y1 = y;
m = n; n = r; r = m % n;
q = (m - r) / n;
}
return n;
}
刘汝佳的
void gcd(int a, int b, int& d, int& x, int& y) {
if (!b) {d = a; x = 1; y = 0; }
else {gcd(b, a % b, d, y, x); y -= x * (a / b); }
}
上面求出的 x x x(当 a > b a>b a>b 时)都是最接近 0 0 0 的正整数。(不知道为什么)
一、求解不定方程
- 对于不定整数方程 a x + b y = m ax+by=m ax+by=m,若 m % g c d ( a , b ) = 0 m \; \% \; gcd(a, b)=0 m%gcd(a,b)=0,则该方程存在整数解,否则不存在整数解。
- a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b), 两边同时乘以 m g c d ( a , b ) \frac{m}{gcd(a,b)} gcd(a,b)m,得 a x ∗ m g c d ( a , b ) + b y ∗ m g c d ( a , b ) = m ax* \frac{m}{gcd(a,b)}+by * \frac{m}{gcd(a,b)}=m ax∗gcd(a,b)m+by∗gcd(a,b)m=m 即 a ∗ x + b ∗ y = m a*x+ b*y = m a∗x+b∗y=m
上面已经列出找一个整数解的方法,在找到 a ∗ x + b ∗ y = g c d ( a , b ) a*x+ b*y = gcd(a,b) a∗x+b∗y=gcd(a,b) 的一组解 x 0 , y 0 x_0,y_0 x0,y0 后,不定方程 a x + b y = m ax+by=m ax+by=m 的一组解满足 x = x 0 ∗ m g c d ( a , b ) , y = y 0 ∗ m g c d ( a , b ) x = x_0*\frac{m}{gcd(a,b)},y = y_0*\frac{m}{gcd(a,b)} x=x0∗gcd(a,b)m,y=y0∗gcd(a,b)m
所以通解为
x
=
x
0
∗
m
g
c
d
(
a
,
b
)
+
k
∗
b
g
c
d
(
a
,
b
)
x = x_0*\frac{m}{gcd(a,b)} + k*\frac{b}{gcd(a,b)}
x=x0∗gcd(a,b)m+k∗gcd(a,b)b,
y
=
y
0
∗
m
g
c
d
(
a
,
b
)
−
k
∗
a
g
c
d
(
a
,
b
)
y = y_0*\frac{m}{gcd(a,b)} - k*\frac{a}{gcd(a,b)}
y=y0∗gcd(a,b)m−k∗gcd(a,b)a (其中
k
k
k 为任意整数)
设
d
=
g
c
d
(
a
,
b
)
d=gcd(a,b)
d=gcd(a,b)
即
x
=
x
0
m
d
+
k
b
d
,
y
=
y
0
m
d
−
k
a
d
(
k
∈
Z
)
x=x_{0} \frac{m}{d}+k\frac{b}{d}, \quad y=y_{0} \frac{m}{d}-k \frac{a}{d} \ (k \in Z)
x=x0dm+kdb,y=y0dm−kda (k∈Z)
通解证明:
令
a
1
=
a
g
c
d
(
a
,
b
)
,
b
1
=
b
g
c
d
(
a
,
b
)
,
m
1
=
m
g
c
d
(
a
,
b
)
a_1=\frac{a}{gcd(a,b)},b_1=\frac{b}{gcd(a,b)},m_1=\frac{m}{gcd(a,b)}
a1=gcd(a,b)a,b1=gcd(a,b)b,m1=gcd(a,b)m
那么
x
,
y
x,y
x,y 的一组解就是
x
0
∗
m
1
,
y
0
∗
m
1
x_{0}*m_1,y_0*m_1
x0∗m1,y0∗m1,但是由于满足方程的解无穷多个,在实际的解题中一般都会去求解
x
x
x 或是
y
y
y 的最小正数的值。以求
x
x
x 为例,又该如何求解呢?还是从方程入手,现在的
x
,
y
x,y
x,y 已经满足
a
∗
x
+
b
∗
y
=
m
a*x+b*y=m
a∗x+b∗y=m ,那么
a
∗
(
x
+
n
∗
b
)
+
b
∗
(
y
−
n
∗
a
)
=
m
a*(x+n*b)+b*(y-n*a)=m
a∗(x+n∗b)+b∗(y−n∗a)=m 显然也是成立的。可以得出
x
+
n
∗
b
(
n
=
…
,
−
2
,
−
1
,
0
,
1
,
2
,
…
)
x+n*b(n=…,-2,-1,0,1,2,…)
x+n∗b(n=…,−2,−1,0,1,2,…) 就是方程的所有
x
x
x 解的集合。
由于每一个
x
x
x 都肯定有一个
y
y
y 和其对应,所以在求解
x
x
x 的时候可以不考虑
y
y
y 的取值。取
k
k
k 使得
x
+
k
∗
b
>
0
x+k*b>0
x+k∗b>0 ,
x
x
x 的最小正数值就应该是
(
x
+
k
∗
b
)
%
b
(x+k*b)\%b
(x+k∗b)%b,但是这个值真的是最小的吗??如果我们将方程最有两边同时除以
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b),则方程变为
a
1
∗
x
+
b
1
∗
y
=
m
1
a_1*x+b_1*y=m_1
a1∗x+b1∗y=m1,同上面的分析可知,此时的最小值应该为
(
x
+
k
∗
b
1
)
%
b
1
(x+k*b_1)\%b_1
(x+k∗b1)%b1,由于
b
1
<
=
b
b_1<=b
b1<=b,所以这个值一定会小于等于之前的值。
因此通解应该为
x
+
n
∗
b
g
c
d
(
a
,
b
)
(
n
=
…
,
−
2
,
−
1
,
0
,
1
,
2
,
…
)
x + n * \frac{b}{gcd(a,b)}(n=…,-2,-1,0,1,2,…)
x+n∗gcd(a,b)b(n=…,−2,−1,0,1,2,…)
因此最小正整数解:
(
x
∗
m
d
%
b
1
+
b
1
)
%
b
1
(
b
1
=
b
g
c
d
(
a
,
b
)
)
(x*\frac{m}{d}\%b_{1}+b_{1})\%b_{1} \ (b_1=\frac{b}{gcd(a,b)})
(x∗dm%b1+b1)%b1 (b1=gcd(a,b)b)
如果我们想得到对应的
y
y
y,需要带入原式求解。
也可以参考洛谷这道题的题解
code:
//不定方程
void linear_equation(int a, int b, int c, int &x, int &y) {
int d = exgcd(a, b, x, y);
if (c % d)
return ;
int k = c / d;
x *= k; y *= k; // 一组解
return;
}
二、求解模线性方程(线性同余方程)与逆元
同余式
结论:对于同余方程
a
x
≡
b
%
m
o
d
ax \equiv b \ \% \ mod
ax≡b % mod ,当且仅当
g
c
d
(
a
,
m
o
d
)
∣
b
(
即
b
%
g
c
d
(
a
,
m
o
d
)
=
=
0
)
gcd(a,mod) | b(即b \ \% \ gcd(a,mod) == 0)
gcd(a,mod)∣b(即b % gcd(a,mod)==0),方程存在解,且有
g
c
d
(
a
,
m
o
d
)
gcd(a,mod)
gcd(a,mod) 个解。
存在解的原因:求解方程
a
x
≡
b
%
m
o
d
ax≡b \ \% mod
ax≡b %mod 相当于求解方程
a
x
+
(
−
m
o
d
×
y
)
=
b
ax+ (-mod \times y)= b
ax+(−mod×y)=b, (
x
,
y
x, y
x,y 为整数)
a
x
≡
b
%
m
o
d
ax \equiv b \% mod
ax≡b%mod
⟺
\Longleftrightarrow
⟺
a
x
%
m
o
d
=
b
%
m
o
d
ax \% mod = b \, \% \,mod
ax%mod=b%mod
算法导论上有两个定理:
定理一:设
d
=
g
c
d
(
a
,
m
o
d
)
d = gcd(a, mod)
d=gcd(a,mod),假定对整数
x
′
,
y
′
x', y'
x′,y′, 有
d
=
a
x
′
+
n
y
′
d = ax' + ny'
d=ax′+ny′, 如果
d
∣
b
d | b
d∣b , 则方程
a
x
=
b
(
%
m
o
d
)
ax = b(\% \ mod)
ax=b(% mod)有一个解的值为
x
0
x_0
x0, 满足:
x
0
=
x
′
(
b
d
)
(
%
m
o
d
)
x_0 = x'(\frac{b}{d})(\% mod)
x0=x′(db)(%mod)
从这我们可以发现不定方程的解没有限制,而同余方程的解是
<
m
o
d
<mod
<mod 的
定理二:假设方程
a
x
≡
b
%
m
o
d
ax \equiv b \ \% \ mod
ax≡b % mod 有解,
x
0
x_0
x0 是方程的任意一个解, 则方程对模
m
o
d
mod
mod 恰有
d
d
d 个不同的解, 分别为:
x
i
=
x
0
+
i
∗
(
m
o
d
d
)
x_i = x_0 + i * (\frac{mod}{d} )
xi=x0+i∗(dmod), 其中
i
=
0
,
1
,
2
,
3......
d
−
1
i = 0,1,2,3......d - 1
i=0,1,2,3......d−1
有了这两个定理, 解方程就不难了。
// 模线性方程
bool modular_linear_equation(int a, int b, int mod) {
int x, y, x0, i;
int d = exgcd(a, mod, x, y);
if (b % d)
return false;
x0 = x * (b / d) % mod; //特解
for(i = 0; i < d; i++)
printf("%d\n", (x0 + i * (mod / d)) % mod);
return true;
}
同余方程
a
x
≡
b
%
m
o
d
ax≡b \ \% \ mod
ax≡b % mod,如果
g
c
d
(
a
,
m
o
d
)
=
1
gcd(a,mod)= 1
gcd(a,mod)=1,则方程只有唯一解。
在这种情况下,如果
b
=
1
b = 1
b=1,同余方程就是
a
x
≡
1
%
m
o
d
ax \equiv 1 \ \% \ mod
ax≡1 % mod,
g
c
d
(
a
,
m
o
d
)
=
1
gcd(a,mod)= 1
gcd(a,mod)=1。
这时称求出的
x
x
x 为
a
a
a 的对模
m
o
d
mod
mod 乘法的逆元。
对于同余方程
a
x
=
1
%
m
o
d
ax= 1 \ \% \ mod
ax=1 % mod,
g
c
d
(
a
,
m
o
d
)
=
1
gcd(a,mod)= 1
gcd(a,mod)=1 的求解就是求解方程
a
x
+
m
o
d
×
y
=
1
ax+ mod\times y= 1
ax+mod×y=1,
x
,
y
x, y
x,y 为整数。这个可用扩展欧几里德算法求出,原同余方程的唯一解就是用扩展欧几里德算法得出的
x
x
x 。
code:
ll inv(ll a, ll mod) {
ll d, x, y;
d = exgcd(a, mod, x, y);
return (d == 1) ? (x % mod + mod) % mod : -1;
}
例题
poj-2115
题意:求
f
o
r
(
i
n
t
i
=
a
;
i
!
=
b
;
i
+
=
c
,
i
%
=
(
1
<
<
k
)
)
for \;(int \; i = a; \; i \; != \; b; \; i += c, \; i \%= (1 <<k )\; )
for(inti=a;i!=b;i+=c,i%=(1<<k)) 执行的次数
思路:
即求解
c
×
x
+
2
k
×
y
=
b
−
a
c\times x+ 2^{k} \times y=b-a
c×x+2k×y=b−a
如果
d
=
g
c
d
(
c
,
2
k
)
d=gcd(c,2^{k})
d=gcd(c,2k) 不能被
b
−
a
b-a
b−a 整除,则说明无解。
用
e
x
g
c
d
exgcd
exgcd 求出一组
c
x
∗
m
g
c
d
(
2
k
,
c
)
+
2
k
y
∗
m
g
c
d
(
2
k
,
c
)
=
m
cx* \frac{m}{gcd(2^{k},c)}+{2^{k}}{y}*\frac{m}{gcd(2^{k},c)}=m
cx∗gcd(2k,c)m+2ky∗gcd(2k,c)m=m 的解
即
c
x
+
2
k
y
=
g
c
d
(
2
k
,
c
)
cx+2^{k}y=gcd(2^{k},c)
cx+2ky=gcd(2k,c)
然后两边乘上
(
b
−
a
)
d
\frac{(b-a)}{d}
d(b−a) 即为一个解
x
0
x_0
x0,然后输出最小正整数解即可。
code:
#include<iostream>
#include<algorithm>
#define ll long long
#define ld long double
#define ull unsigned long long
using namespace std;
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, y, x);
ll t = x;
y = y - a / b * t;
return r;
}
int main()
{
ll a, b, c, k;
while(cin >> a >> b >> c >> k && a + b + c + k)
{
ll x, y, n;
n = 1ll << k;
ll d = exgcd(c, n, x, y);
if((b - a) % d){
cout<<"FOREVER"<<endl;
}
else
{
n /= d;
ll x0 = (x * ((b - a) / d) % n + n) % n;
cout << x0 << endl;
}
}
return 0;
}
poj-2142-The Balance
题目大意:
给两种没有数量限制的两种砝码,重量分别为 a 和 b,现在要在天平上称重量为 d 的物品,砝码可以放在天平的两侧,问能不能称出 d,不能输出-1,否则输出使用两种砝码的个数,要求个数和最小。
思路:
显然同种砝码不能放两侧,因为会抵消,没有意义,因此要么两种砝码放同侧,要么放异侧,问题就可以转换成求解
a
x
+
b
y
=
d
ax+by=d
ax+by=d 这个方程。设
∣
x
∣
|x|
∣x∣ 表示第一种砝码的数量,
∣
y
∣
|y|
∣y∣ 表示第二种砝码的数量,求解出来
x
,
y
x,y
x,y 同号则在一侧,否则在异侧。
我们需要最小化
∣
x
∣
+
∣
y
∣
|x|+|y|
∣x∣+∣y∣
可以猜一手结论,用拓展欧几里得分别求出最小的正整数
x
x
x,然后带入方程求出对应的
y
y
y,然后再用拓展欧几里得求最小正整数
y
y
y,带入方程求对应的
x
x
x。再将得到的两种
(
x
+
y
)
(x+y)
(x+y) 的值比较,输出小的。
code:
#include<iostream>
#include<algorithm>
#define ll long long
#define ld long double
#define ull unsigned long long
using namespace std;
ll a, b, d;
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, y, x);
ll t = x;
y = y - a / b * t;
return r;
}
void work()
{
ll x, y;
ll g = exgcd(a, b, x, y);
if(d % g) cout << -1 << endl;
else
{
ll ta = a / g, tb = b / g;
ll x0 = (x * d / g % tb + tb) % tb;
ll yy = (d - a * x0) / b;
ll y0 = (y * d / g % ta + ta) % ta;
ll xx = (d - b * y0) / a;
if(x0 + abs(yy) <= y0 + abs(xx))
cout << x0 << " " << abs(yy) << endl;
else cout << abs(xx) << " " << y0 << endl;
}
}
int main()
{
while(cin >> a >> b >> d && (a || b || d))
work();
return 0;
}
poj-1061-青蛙的约会
题意:
一条首尾相接的数轴上,青蛙
A
A
A 的出发点坐标是
x
x
x,青蛙
B
B
B 的出发点坐标是
y
y
y。青蛙
A
A
A 一次能跳
m
m
m 米,青蛙
B
B
B一次能跳
n
n
n 米,两只青蛙跳一次所花费的时间相同。数轴总长
l
l
l 米。现在要你求出它们跳了几次以后才会碰面。
思路:
线性同余方程
设 A 的起点为 A,B 的起点为 B,因为两只青蛙同时跳,所以步数一样多
如果能相遇,最后位置坐标一样
则
A
+
m
x
(
%
l
)
=
B
+
n
x
(
%
l
)
⟹
(
m
−
n
)
x
(
%
l
)
=
A
−
B
(
%
l
)
⟹
(
m
−
n
)
x
≡
B
−
A
(
%
l
)
A+mx(\%l)=B+nx(\%l) \Longrightarrow (m-n)x(\%l)=A-B(\%l) \Longrightarrow (m-n)x \equiv B-A (\%l)
A+mx(%l)=B+nx(%l)⟹(m−n)x(%l)=A−B(%l)⟹(m−n)x≡B−A(%l)
code:
#include<iostream>
#include<algorithm>
#define ll long long
#define ld long double
#define ull unsigned long long
using namespace std;
ll x, y, m, n, l, A, B;
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, y, x);
y = y - a / b * x;
return r;
}
void work()
{
cin >> A >> B >> m >> n >> l;
ll d = exgcd(n - m, l, x, y);
if((A - B) % d) cout << "Impossible\n";
else
{
ll ans = (x * (A - B) / d % l + l) % l;
cout << ans << endl;
}
}
int main()
{
work();
return 0;
}
#include<iostream>
#include<algorithm>
#define ll long long
#define ld long double
#define ull unsigned long long
using namespace std;
ll x, y, a, b;
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, y, x);
y = y - a / b * x;
return r;
}
void work()
{
cin >> a >> b;
ll d = exgcd(a, b, x, y);
cout << (x % b + b) % b << endl;
}
int main()
{
work();
return 0;
}
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#define ll long long
using namespace std;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1;y=0;
return a;
}
else
{
ll tx,ty;
ll d=exgcd(b,a%b,tx,ty);
x=ty;y=tx-(a/b)*ty;
return d;
}
}
int main()
{
ll a,b,k,x,y;scanf("%lld%lld%lld",&a,&b,&k);
ll d=exgcd(a,b,x,y);
if(k%d){puts("no solution!");return 0;}
else
{
x=x*k/d;
y=(k-a*x)/b;
}
printf("%lld %lld\n",x,y);
return 0;
}
#include<iostream>
#include<algorithm>
#define ll long long
#define ld long double
#define ull unsigned long long
using namespace std;
ll x, y, a, b;
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, y, x);
y = y - a / b * x;
return r;
}
void work()
{
//cin >> a >> b;
ll d = exgcd(a, b, x, y);
if(d != 1) cout << "sorry\n";
else
{
x = (x % b + b) % b;
y = (1 - a * x) / b;
cout << x << " " << y << endl;
}
}
int main()
{
while(cin >> a >> b)
work();
return 0;
}