题意:
定义一个函数如下:
R ( a , b ) = { R ( b , a ) i f a < b R ( ⌊ a b ⌋ , b ) i f a > = b > 1 a i f a > = b = 1 R(a,b)=\begin{cases} R(b,a)\quad if \ a<b \\ R(\lfloor\frac{a}{b}\rfloor,b)\quad if\ a>=b >1 \\ a \quad if\ a>=b=1 \end{cases} R(a,b)=⎩⎪⎨⎪⎧R(b,a)if a<bR(⌊ba⌋,b)if a>=b>1aif a>=b=1
现在给你两个数g,h,分别代表gcd(a,b)=g,R(a,b)=h,现在要求你构造出a和b,输出a和b
Solution:
假设x,y为答案
因 为 g c d ( x , y ) = g , 所 以 我 们 假 设 x = a g , y = b g ( 在 推 导 过 程 中 默 认 b > a ) , 由 最 大 公 因 数 性 质 可 知 g c d ( a , b ) = 1 { g c d ( a , b ) = 1 R ( a g , b g ) = h 换 种 写 法 { g c d ( a , b ) = 1 R ( ⌊ b a ⌋ , a g ) = h 因为gcd(x,y)=g,所以我们假设x=ag,y=bg(在推导过程中默认b>a),由最大公因数性质可知gcd(a,b)=1 \\ \begin{cases}gcd(a,b)=1\\ R(ag,bg)=h\end{cases} \\ 换种写法 \\ \begin{cases}gcd(a,b)=1\\ R(\lfloor\frac{b}{a}\rfloor,ag)=h\end{cases} 因为gcd(x,y)=g,所以我们假设x=ag,y=bg(在推导过程中默认b>a),由最大公因数性质可知gcd(a,b)=1{ gcd(a,b)=1R(ag,bg)=h换种写法{ gcd(a,b)=1R(⌊ab⌋,ag)=h
因为要得到R(x,y)=h,所以递归到底后肯定会出现R(h,1)
我们倒着推上去,保持左边的h不变
R ( h , 1 ) = R ( h , [ h 2 , 2 h 2 ) ) = R ( h , [ h 3 , 2 h 3 ) ) = . . . = R ( h , [ h i , 2 h i ) ) R(h,1)=R(h,[h^2,2h^2))=R(h,[h^3,2h^3))=...=R(h,[h^i,2h^i)) R(h,1)=R(h,[h2,2h2))=R(h,[h3,2h3))=...=R(h,[hi,2hi))
所以 a g ∈ [ h i , 2 h i ) ag∈[h^i,2h^i) ag∈[hi,2hi),因此我们只要先找出大于g的 h i h^i hi,再保证其能整除g,即 x = h i + ( g − h i % g ) x=h^{i}+(g-h^i\%g) x=hi+(g−hi%g),这样就能保证x整除g
对于 ⌊ b a ⌋ = h \lfloor\frac{b}{a}\rfloor=h ⌊ab⌋=h,通过带余除法的性质可知 b = a h + [ 0 , a ) b=ah+[0,a) b=ah+[0,a),对于这个可以枚举去求。也可以发现这个结果 b = a h + 1 b=ah+1 b=ah+1能满足 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1
证明:
g c d ( a , b ) = g c d ( a , a h + 1 ) = g c d ( a h + 1 , a ) = g c d ( a , 1 ) = g c d ( 1 , 0 ) gcd(a,b) \\ =gcd(a,ah+1) \\ =gcd(ah+1,a) \\ =gcd(a,1) \\ =gcd(1,0) gcd(a,b)=gcd(a,ah+1)=gcd(ah+1,a)=gcd(a,1)=gcd(1,0)
所以最后的结果就是
x = a g = h i + ( g − h i % g ) y = b g = x g ∗ ( x h g + 1 ) x=ag=h^i+(g-h^i\%g) \\ y=bg=\frac{x}{g}*(\frac{xh}{g}+1) x=ag=hi+(g−hi%g)y=bg=gx∗(gxh+1)
代码
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f3f3f3f3f
typedef long long ll;
typedef pair<int,int>P;
int t;
ll g,h;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&g,&h);
ll q=1;
while(q<=g)q=q*h;
if(q%g)q=q+(g-q%g);
ll a=q/g;
ll b=a*h+1;
a=a*g;
b=b*g;
printf("%lld %lld\n",a,b);
}
return 0;
}