analysis
首先,模拟不能过
那么就是一道数学:
设
青
蛙
a
从
位
置
A
开
始
,
步
长
为
m
,
青
蛙
b
从
位
置
B
开
始
,
步
长
为
n
设青蛙a从位置A开始,步长为m,青蛙b从位置B开始,步长为n
设青蛙a从位置A开始,步长为m,青蛙b从位置B开始,步长为n
则
a
的
位
置
:
A
+
k
m
,
b
的
位
置
:
B
+
k
n
,
其
中
,
k
为
跳
跃
步
数
则a的位置:A+km,b的位置:B+kn,其中,k为跳跃步数
则a的位置:A+km,b的位置:B+kn,其中,k为跳跃步数
若
a
,
b
相
遇
,
则
有
同
余
方
程
:
A
+
k
m
≡
B
+
k
n
(
m
o
d
L
)
若a,b相遇,则有同余方程:A+km\equiv B+kn\pmod L
若a,b相遇,则有同余方程:A+km≡B+kn(modL)
这
个
等
价
于
A
+
k
m
−
(
B
+
k
n
)
=
x
L
,
x
∈
Z
这个等价于A+km-(B+kn)=xL,x\in Z
这个等价于A+km−(B+kn)=xL,x∈Z
整
理
方
程
得
到
:
k
(
m
−
n
)
−
x
L
=
B
−
A
整理方程得到:k(m-n)-xL=B-A
整理方程得到:k(m−n)−xL=B−A
由
于
这
是
个
丢
番
图
方
程
(
不
定
方
程
)
,
x
,
k
有
多
个
解
,
那
么
不
妨
设
x
>
0
,
则
:
由于这是个丢番图方程(不定方程),x,k有多个解,那么不妨设x>0,则:
由于这是个丢番图方程(不定方程),x,k有多个解,那么不妨设x>0,则:
k
(
n
−
m
)
+
x
L
=
A
−
B
k(n-m)+xL=A-B
k(n−m)+xL=A−B
此
时
将
(
n
−
m
)
看
成
a
,
L
看
成
b
,
A
−
B
看
成
c
此时将(n-m)看成a,L看成b,A-B看成c
此时将(n−m)看成a,L看成b,A−B看成c
那
么
这
就
是
解
一
个
不
定
方
程
a
k
+
b
y
=
c
中
k
的
最
小
正
整
数
解
了
那么这就是解一个不定方程ak+by=c中k的最小正整数解了
那么这就是解一个不定方程ak+by=c中k的最小正整数解了
当
然
,
不
定
方
程
有
解
的
判
断
条
件
:
(
a
,
b
)
∣
c
当然,不定方程有解的判断条件:(a,b)|c
当然,不定方程有解的判断条件:(a,b)∣c
若
(
n
−
m
,
L
)
∣
(
A
−
B
)
,
我
们
就
可
以
用
扩
展
欧
几
里
得
算
出
k
(
n
−
m
)
+
x
L
=
(
n
−
m
,
L
)
的
一
组
解
了
若(n-m,L)|(A-B),我们就可以用扩展欧几里得算出k(n-m)+xL=(n-m,L)的一组解了
若(n−m,L)∣(A−B),我们就可以用扩展欧几里得算出k(n−m)+xL=(n−m,L)的一组解了
注意,这里的各项系数a,b要大于等于0,否则欧几里得定理就不成立了
若a小于0,反号就好,b本来就是可以通过x的取值做到大于0的
求
出
一
个
特
解
k
0
后
,
k
(
n
−
m
)
+
x
L
=
(
n
−
m
,
L
)
的
通
解
k
i
=
k
0
−
φ
b
(
a
,
b
)
,
φ
∈
Z
求出一个特解k_0后,k(n-m)+xL=(n-m,L)的通解k_i=k_0-\varphi \frac{b}{(a,b)},\varphi\in Z
求出一个特解k0后,k(n−m)+xL=(n−m,L)的通解ki=k0−φ(a,b)b,φ∈Z
(证明在文后)
那
么
,
对
于
原
方
程
,
通
解
的
系
数
要
乘
上
一
个
A
−
B
(
a
,
b
)
那么,对于原方程,通解的系数要乘上一个\frac{A-B}{(a,b)}
那么,对于原方程,通解的系数要乘上一个(a,b)A−B
对
于
最
小
解
,
就
是
通
解
中
最
靠
近
0
的
那
一
个
,
处
理
方
式
见
代
码
对于最小解,就是通解中最靠近0的那一个,处理方式见代码
对于最小解,就是通解中最靠近0的那一个,处理方式见代码
code
#include <bits/stdc++.h>
using namespace std;
#define loop(i, start, end) for (register int i = start; i <= end; ++i)
#define anti_loop(i, start, end) for (register int i = start; i >= end; --i)
#define clean(arry, num) memset(arry, num, sizeof(arry))
#define ll long long
#define isdegit(a) ((a >= '0' && a <= '9'))
template <typename T>
void read(T &x) {
x = 0;
char r = getchar();
T neg = 1;
while (!isdegit(r)) {
if (r == '-')
neg = -1;
r = getchar();
}
while (isdegit(r)) {
x = (x << 1) + (x << 3) + r - '0';
r = getchar();
}
x *= neg;
}
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
ll res = exgcd(b, a % b, x, y);
ll x1 = x;
x = y;
y = x1 - (a / b) * y;
return res;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("datain.txt", "r", stdin);
#endif
ll A, n, B, m, L;
read(A);
read(B);
read(m);
read(n);
read(L);
ll x = 0, y = 0;
if (n < m)
swap(n, m), swap(A, B);
ll b = L, a = n - m, c = A - B;
ll gcd = exgcd(a, b, x, y);
if (c % gcd || m == n) {
printf("Impossible\n");
} else {
printf("%lld\n", ((x * c / gcd) % (b / gcd) + b / gcd) % (b / gcd));
}
return 0;
}
相关证明
- 关于通解
对于方程: a x + b y = ( a , b ) ax+by=(a,b) ax+by=(a,b)
假 设 已 经 求 出 一 组 解 x 0 , y 0 , 且 其 他 解 设 为 x i , y i 假设已经求出一组解x_0,y_0,且其他解设为x_i,y_i 假设已经求出一组解x0,y0,且其他解设为xi,yi
则 a x 0 + b y 0 = ( a , b ) 则ax_0+by_0=(a,b) 则ax0+by0=(a,b)
a x i + b y i = ( a , b ) ax_i+by_i=(a,b) axi+byi=(a,b)
则 a x 0 + b y 0 = a x i + b y i 则ax_0+by_0=ax_i+by_i 则ax0+by0=axi+byi
同 时 除 以 ( a , b ) 得 : a ( a , b ) ( x 0 − x i ) = b ( a , b ) ( y i − y 0 ) 同时除以(a,b)得:\frac{a}{(a,b)}(x_0-x_i)=\frac{b}{(a,b)}(y_i-y_0) 同时除以(a,b)得:(a,b)a(x0−xi)=(a,b)b(yi−y0)
即 a ( a , b ) ∣ b ( a , b ) ( y i − y 0 ) 即\frac{a}{(a,b)}|\frac{b}{(a,b)}(y_i-y_0) 即(a,b)a∣(a,b)b(yi−y0)
由 ( a ( a , b ) , b ( a , b ) ) = 1 , 有 ( x 0 − x 1 ) ∣ b ( a , b ) 由(\frac{a}{(a,b)},\frac{b}{(a,b)})=1,有(x_0-x_1)|\frac{b}{(a,b)} 由((a,b)a,(a,b)b)=1,有(x0−x1)∣(a,b)b
等 价 变 换 后 得 x i = x 0 − φ b ( a , b ) , φ ∈ Z 等价变换后得x_i=x_0-\varphi \frac{b}{(a,b)},\varphi \in Z 等价变换后得xi=x0−φ(a,b)b,φ∈Z