题目如下:
题解 or 思路
我们可以将题目 抽象 成数学模型
x
+
k
d
≡
y
(
m
o
d
n
)
x + kd \equiv y\ (mod\ n)
x+kd≡y (mod n)
x
+
k
d
=
y
+
a
∗
n
x + kd = y + a * n
x+kd=y+a∗n
k
∗
d
−
a
∗
n
=
y
−
x
k*d - a*n = y - x
k∗d−a∗n=y−x @式子
在这里
k
k
k,
a
a
a 是变量,其余是常数
我们可以扩展欧几里得算法得到:
x
∗
d
+
y
∗
n
=
g
c
d
(
n
,
d
)
x*d + y*n = gcd(n, d)
x∗d+y∗n=gcd(n,d) #式子
根据裴蜀定理:如果 (y - x) 不能被
g
c
d
(
n
,
d
)
gcd(n, d)
gcd(n,d) 整除,那么一定无解
因为@式子等式右边是
y
−
x
y - x
y−x
g
c
d
(
n
,
d
)
不一定是等于
y
−
x
gcd(n, d) 不一定是等于 y - x
gcd(n,d)不一定是等于y−x
我们将 #式子 两边同时乘以 y − x g c d ( n , d ) \frac{y - x}{gcd(n,d)} gcd(n,d)y−x 就可以得到 @式子
题目是要让我们求次数,也就是求等式
k
k
k 的值
k
=
k
0
+
z
∗
y
−
x
g
c
d
(
n
,
d
)
k = k_0 + z * \frac{y - x}{gcd(n, d)}
k=k0+z∗gcd(n,d)y−x
那么可得
k
k
k 的最小值是:
k
0
%
n
g
c
d
(
n
,
d
)
k_0\ \%\ \frac{n}{gcd(n, d)}
k0 % gcd(n,d)n
AC 代码如下:
#define int long long
int n, d, x, y;
int exgcd(int a, int b, int &x, int &y)
{
if (b == 0)
{
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y = y - a / b * x;
return d;
}
void solve()
{
cin >> n >> d >> x >> y;
int a, b;
int gcd = exgcd(d, n, a, b);
if ((y - x) % gcd)
{
cout << "Impossible\n";
return;
}
else
{
a *= (y - x) / gcd;
n /= gcd;
cout << (a % n + n) % n << '\n';
}
}
signed main()
{
buff;
int _;
cin >> _;
while (_--)
solve();
}
/*
(x + k * d) % n == y
*/