\(\sf Also\ 2021.6.19\)。
\(\sf A-Euklid\)
解法
这个构造真的好精妙啊。
不妨设
\[b=g\left \lceil \frac{h^k}{g} \right \rceil,a=hb+g
\]
那么 \(\frac{b}{g}=\left \lceil \frac{h^k}{g} \right \rceil,\frac{a}{g}=h\left \lceil \frac{h^k}{g} \right \rceil+1\)。只需要二者互质就能达到 \(\gcd(a,b)=g\) 的条件。容易发现这在 \(\left \lceil \frac{h^k}{g} \right \rceil>1\) 时成立。
那我们不妨取最小的 \(k\) 使得 \(\left \lceil \frac{h^k}{g} \right \rceil>1\) 成立,此时可以推出 \(g<h^k\)。\(h^k\) 不会很大,因为即使 \(h=g\) 这种比较极端的情况也有 \(\left \lceil \frac{h^2}{g} \right \rceil>1\) 且 \(h^2\le 4\times 10^{10}\)。
此时有 \(h^k\le b<2\times h^k\)。对于后一个范围是因为 \(b<h^k+g<2\times h^k\)。
这有什么用呢?我们尝试带入 \(a,b\) 来计算这个函数。
首先有 \(\text{R}(a,b)=\text{R}(b,h)\),因为 \(\frac{g}{b}<1\)。之后将 \(b\) 不断除以 \(h\),容易发现 \(b\) 的取值范围是同构的,最后一次有 \(k=1\) 就可以得到 \(\text{R}(h,1)\) 也即达到我们的目标。
代码
#include <bits/stdc++.h>
using namespace std;
#define rep(i,_l,_r) for(int i=(_l),_end=(_r);i<=_end;++i)
#define print(x,y) write(x),putchar(y)
int read() {
int x=0; bool f=0; char s;
while((s=getchar())>'9' or s<'0') f|=(s=='-');
while(s>='0' and s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
return f?-x:x;
}
void write(int x) {
if(x<0) return (void)(putchar('-'),write(-x));
if(x>9) write(x/10);
putchar(x%10^48);
}
typedef long long ll;
int main() {
freopen("euklid.in","r",stdin); freopen("euklid.out","w",stdout);
rep(T,1,read()) {
ll g=read(),h=read(),tmp=h;
while(tmp<=g) tmp=tmp*h;
ll a=((tmp-1)/g+1)*g,b=a*h+g;
printf("%lld %lld\n",a,b);
}
return 0;
}