zoukankan      html  css  js  c++  java
  • 2019HDU多校第五场A fraction —— 辗转相除法|类欧几里得

    题目

    设 $ab^{-1} = x(mod p)$,给出 $x,p$,要求最小的 $b$,其中 $0< a < b, 1 < x<p, 3 leq xleq {10}^{15}$.

    分析

    比赛中,首先就想用扩展欧几里得解出一个可行 $b$,然后枚举 $kb \% p$ 的最小值,然后发现复杂度爆炸。

    看题解,用了一种非常巧妙地方法,

    $ecause 0 < a=bx-pt < b$

    $ herefore frac{p}{x} < frac{b}{t} < frac{p}{x-1}$

    按题解,这是一个经典问题,可以用辗转相除法解决。

    如,对于 $frac{a}{b} < frac{x}{y} < frac{c}{d}$

    若 $left lfloor frac{a}{b} ight floor eq left lfloor frac{c}{d} ight floor$,直接取 $x = left lfloor frac{a}{b} ight floor, y = 1$;

    若 $left lfloor frac{a}{b} ight floor =  left lfloor frac{c}{d} ight floor$,先统一减去整数部分,然后取倒数,即 $frac{d}{c} < frac{y}{x} < frac{b}{a}$.

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    ll p, x;
    
    //q求满足a/b < x/y < c/d 的最小的x和y
    void f(ll a, ll b, ll c, ll d, ll& x, ll& y)
    {
        ll tmp = (a+b-1)/b;
        if(tmp <= c/d)
        {
            x=tmp;
            y=1;
            return;
        }
    
        a -= b*(tmp-1);
        //x -= y*tmp;
        c -= d*(tmp-1);
        f(d, c, b, a, y, x);
        x += y*(tmp-1);
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%lld%lld", &p, &x);
            ll b, t;
            f(p, x, p, x-1, b, t);
            ll a = b*x-p*t;
            printf("%lld/%lld
    ", a, b);
        }
        return 0;
    }

    续:后来知道这种方法叫类欧几里得算法,与欧几里得相似,采用辗转相除的方法。

  • 相关阅读:
    Mysql int类型你了解多少
    java 小程序开发PKCS7Padding 解密相关问题
    Shiro+JWT 实现权限管理(二)--JWT
    Shiro+JWT 实现权限管理(一)--Shiro
    HTTP常见状态码
    Java开发之Redis
    微信公众号开发总结(一) --程序入口
    成熟男人需要懂得的100件事
    Java8 Time API与老Date之间的转换
    极光推送工具类
  • 原文地址:https://www.cnblogs.com/lfri/p/11309836.html
Copyright © 2011-2022 走看看