HDUoj6624 fraction(辗转相除法)

HDUoj6624 fraction(辗转相除法)

题目大意

给出一个p和x要求求出最小的b满足
a ≡ b x ( m o d   p ) a\equiv bx(mod\ p) abx(mod p)

解题思路

先对原式进行一些转化
a ≡ b x ( m o d   p ) a = b x − p c ( c ∈ Z ) ∵ 0 ≤ a &lt; b → 0 ≤ b x − p c &lt; b → p x ≤ b c &lt; p x − 1 \begin{aligned} a&amp;\equiv bx(mod\ p)\\ a&amp;=bx-pc(c\in Z)\\ \because &amp;0\le a&lt;b\\ \rightarrow &amp;0\le bx-pc&lt;b\\ \rightarrow&amp;\frac{p}{x}\le \frac{b}{c}&lt;\frac{p}{x-1} \end{aligned} aabx(mod p)=bxpc(cZ)0a<b0bxpc<bxpcb<x1p
原问题就转化成了一个经典问题,求满足值在所给的两分数之间时,最小的分子分母是多少。

⌈ p x ⌉ = d \left\lceil\frac{p}{x}\right\rceil=d xp=d,当 ⌊ p x − 1 ⌋ ≥ d \left\lfloor\frac{p}{x-1}\right\rfloor\ge d x1pd时,显然有b=d,c=1为最优解,但是当不满足这个条件时,首先可以发现 p x \frac{p}{x} xp p x − 1 \frac{p}{x-1} x1p之间的差值必然小于1,由此
p x − ( d − 1 ) ≤ b c − ( d − 1 ) &lt; p x − 1 − ( d − 1 ) \begin{aligned} \frac{p}{x}-(d-1)\le \frac{b}{c}-(d-1)&lt;\frac{p}{x-1}-(d-1) \end{aligned} xp(d1)cb(d1)<x1p(d1)
此时可以发现不等式外侧的两个值都变成了真分数,只要对其作倒数就又变成了假分数则又可以进行上述操作,最终到达满足条件的答案再倒退回来就是答案

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL p,a;
//solve "pa/pb<x/y<=qa/qb" 's min(y),min(x)
void solve(LL pa,LL pb,LL qa,LL qb,LL &x,LL &y)
{
	LL z=(pa+pb-1)/pb;
	if(z<=qa/qb){
		x=z;y=1;
		return ;
	}
	pa-=(z-1)*pb;qa-=(z-1)*qb;
	solve(qb,qa,pb,pa,y,x);
	x+=(z-1)*y;
}
int main()
{
	int t;
	scanf("%d",&t);
	LL x,y;
	while(t--)
	{
		scanf("%lld%lld",&p,&a);
		solve(p,a,p,a-1,x,y);
		printf("%lld/%lld\n",x*a-p*y,x);
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值