>Link
luogu P1516
>Description
求关于 t t t的同余方程 x + t n ≡ y + t m ( m o d L ) x+tn\equiv y+tm(modL) x+tn≡y+tm(modL)
>解题思路
把常数和未知数分开:
t
n
−
t
m
≡
y
−
x
(
m
o
d
L
)
tn-tm\equiv y-x(modL)
tn−tm≡y−x(modL)
然后同余转换成等式:
t
n
−
t
m
+
s
L
=
y
−
x
tn-tm+sL=y-x
tn−tm+sL=y−x
t
(
n
−
m
)
+
s
L
=
y
−
x
t(n-m)+sL=y-x
t(n−m)+sL=y−x
t
,
s
t,s
t,s都是未知数,现在就是如
a
x
+
b
y
=
c
ax+by=c
ax+by=c 的式子
为使得
a
,
b
a,b
a,b 互质(就可以用扩欧求了),
a
,
b
a,b
a,b 同除以
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b),那等式右边的
c
c
c 也需要除以
(
a
,
b
)
(a,b)
(a,b)。如果
c
c
c 不能整除
(
a
,
b
)
(a,b)
(a,b),就说明无解了。
设
g
=
g
c
d
(
a
,
b
)
g=gcd(a,b)
g=gcd(a,b),现在求
a
g
x
+
b
g
y
=
c
g
\frac a gx+\frac b gy=\frac c g
gax+gby=gc。
a
g
,
b
g
\frac a g,\frac b g
ga,gb 已互质,用扩展欧几里得可以求出
a
g
x
+
b
g
y
=
1
\frac a gx+\frac b gy=1
gax+gby=1 的解,两边再同乘
c
g
\frac c g
gc 就可以得到题目要求的
t
t
t 了。
要注意负数,要把它变成非负数。
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std;
LL gcd (LL a, LL b)
{
if (!b) return a;
return gcd (b, a % b);
}
void ex_gcd (LL a, LL b, LL &x, LL &y)
{
if (!b) {x = 1; y = 0; return;}
LL X = x, Y = y;
ex_gcd (b, a % b, X, Y);
x = Y;
y = X - (a / b) * Y;
}
int main()
{
LL p, q, n, m, a, b, c, x, y, g;
scanf ("%lld%lld%lld%lld%lld", &p, &q, &n, &m, &b);
a = ((n - m) % b + b) % b;
c = ((q - p) % b + b) % b;
g = gcd (a, b);
if (c % g != 0)
{
printf ("Impossible");
return 0;
}
a /= g, b /= g, c /= g;
ex_gcd (a, b, x, y);
x = (x % b + b) % b;
x = x * c % b;
printf ("%lld", x);
return 0;
}