\(\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;
}
posted on 2021-06-19 17:04  Oxide  阅读(86)  评论(0编辑  收藏  举报