HDU6624 fraction

HDU6624 fraction

题意:求满足a < b and a ≡ bx (mod p)成立的最小b,并以分数形式输出a / b。
p是质数,3 <= p <= 1e15, 1 < x <p, 1 <= T <= 2e5次查询

思路:由同余的定义考虑将等式转换一下 ,转换成 a = bx - py。
再由题目限制条件可以得到 0 < a = bx - py < b.
由 0 < bx - py 可以得到 p / x < b / y;
由 bx - py < b 可以得到 b /y < p / (x - 1)
所以可以得到 p / x < b / y < p / (x - 1).
然后转换成求 b / a < x / y < d / c.成立的最小x.
dalao们都说这是一个经典问题orz 萌新瑟瑟发抖
大致理解了一下大佬们的想法,辗转相除,和扩展欧几里得比较相似。

算法流程:
假设 p1 = b / a, p2 = d / c.

  1. 如果p1 != p2, 也就是两个分式整数部分不相同,那么x = p1 + 1, y = 1就是成立的最小分式这个显然

  2. p1 == p2. 分式通分一下 (b - a * p1) / a < (x - y * p1) / y < ( d - c * p1) / c
    那么上述不等式中通分相减之后分子都小于分母了。我们的目的是最小化x
    考虑分子分母翻转一下:a / (b - a * p1) > y / (x - y * p1) > c / ( d - c * p1)
    此时不妨令b’ = c, a ’ = ( d - c * p1), x ’ = y, y’ = (x - y * p1), d ’ = b, c ’ = (b - a * p1)
    我们又将问题转换成以一个求解 b’ / a’ < x ’ / y’ < d’ / c’ 成立的最小的x’的子问题,转会步骤1,2递归进行

  3. 于是我们可以将这个新的不等式递归的求解直到p1 != p2。

AC code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

void ex(ll b, ll a, ll d, ll c, ll &x, ll &y){
    ll p1 = b / a, p2 = d / c;
    if(p1 != p2){
        y = 1, x = p1 + 1;
        return ;
    }
    b -= a * p1;
    d -= c * p2;
    ex(c, d, a, b, y, x); //分子分母翻转
    x += y * p1; //递归求解
}

int main(){
    ll p, a;
    int T;
    scanf("%d", &T);
    while(T--){
        scanf("%lld%lld", &p, &a);
        ll x, y;
        ex(p, a, p, a - 1, x, y);
        ll ans = x * a - p * y;
        printf("%lld/%lld\n", ans, x);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值