HDUoj6624 fraction(辗转相除法)
题目大意
给出一个p和x要求求出最小的b满足
a
≡
b
x
(
m
o
d
p
)
a\equiv bx(mod\ p)
a≡bx(mod p)
解题思路
先对原式进行一些转化
a
≡
b
x
(
m
o
d
p
)
a
=
b
x
−
p
c
(
c
∈
Z
)
∵
0
≤
a
<
b
→
0
≤
b
x
−
p
c
<
b
→
p
x
≤
b
c
<
p
x
−
1
\begin{aligned} a&\equiv bx(mod\ p)\\ a&=bx-pc(c\in Z)\\ \because &0\le a<b\\ \rightarrow &0\le bx-pc<b\\ \rightarrow&\frac{p}{x}\le \frac{b}{c}<\frac{p}{x-1} \end{aligned}
aa∵→→≡bx(mod p)=bx−pc(c∈Z)0≤a<b0≤bx−pc<bxp≤cb<x−1p
原问题就转化成了一个经典问题,求满足值在所给的两分数之间时,最小的分子分母是多少。
设
⌈
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
⌊x−1p⌋≥d时,显然有b=d,c=1为最优解,但是当不满足这个条件时,首先可以发现
p
x
\frac{p}{x}
xp与
p
x
−
1
\frac{p}{x-1}
x−1p之间的差值必然小于1,由此
p
x
−
(
d
−
1
)
≤
b
c
−
(
d
−
1
)
<
p
x
−
1
−
(
d
−
1
)
\begin{aligned} \frac{p}{x}-(d-1)\le \frac{b}{c}-(d-1)<\frac{p}{x-1}-(d-1) \end{aligned}
xp−(d−1)≤cb−(d−1)<x−1p−(d−1)
此时可以发现不等式外侧的两个值都变成了真分数,只要对其作倒数就又变成了假分数则又可以进行上述操作,最终到达满足条件的答案再倒退回来就是答案
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);
}
}