「一本通 6.4 例 1」 luogu P1516 青蛙的约会

在这里插入图片描述

analysis

首先,模拟不能过
那么就是一道数学:
设 青 蛙 a 从 位 置 A 开 始 , 步 长 为 m , 青 蛙 b 从 位 置 B 开 始 , 步 长 为 n 设青蛙a从位置A开始,步长为m,青蛙b从位置B开始,步长为n aAm,bB,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+kmB+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,xZ
整 理 方 程 得 到 : k ( m − n ) − x L = B − A 整理方程得到:k(m-n)-xL=B-A :k(mn)xL=BA
由 于 这 是 个 丢 番 图 方 程 ( 不 定 方 程 ) , 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(nm)+xL=AB
此 时 将 ( n − m ) 看 成 a , L 看 成 b , A − B 看 成 c 此时将(n-m)看成a,L看成b,A-B看成c (nm)a,Lb,ABc
那 么 这 就 是 解 一 个 不 定 方 程 a k + b y = c 中 k 的 最 小 正 整 数 解 了 那么这就是解一个不定方程ak+by=c中k的最小正整数解了 ak+by=ck
当 然 , 不 定 方 程 有 解 的 判 断 条 件 : ( 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)的一组解了 (nm,L)(AB),k(nm)+xL=(nm,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(nm)+xL=(nm,L)ki=k0φ(a,b)b,φZ
(证明在文后)
那 么 , 对 于 原 方 程 , 通 解 的 系 数 要 乘 上 一 个 A − B ( a , b ) 那么,对于原方程,通解的系数要乘上一个\frac{A-B}{(a,b)} ,,(a,b)AB
对 于 最 小 解 , 就 是 通 解 中 最 靠 近 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(x0xi)=(a,b)b(yiy0)
    即 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(yiy0)
    由 ( 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,(x0x1)(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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AndrewMe8211

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值