1 条题解
-
0
自动搬运
来自洛谷,原作者为

Mihari
您也是这样吧,因为战斗到底——因为努力求生,现在,才能站在这里。搬运于
2025-08-24 22:27:11,当前版本为作者最后更新于2021-06-19 16:51:42,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
壹、题目描述 ¶
定义函数
$$R(a,b)= \begin{cases} R(b,a) &a1 \\ a&b=1 \end{cases} $$给定 ,请找到 使得 . 保证 ,可以证明,存在 的解。
贰、题解 ¶
显然一道构造题,但是挺难想到。下面我们不妨假设 .
首先想到的就是去考察 的性质,如果你打表,你会发现......不,你什么都发现不了。
但是我们可以利用人类智慧,首先一定有 ,更一般地,有 ,我们只需要保证 即可。
也即,有 ,如果我们不考虑 的限制,那么我们可以直接构造 ,但是像这样由一边除到尽头,我们始终需要强制让一边为 ,如 ,而此时我们是万般不能让 的(除了可能存在的一些特殊情况)。所以,这种 “一边除到底” 好是好,但是不能满足所有条件。
但是我们可以考虑,当 完之后,得到 ,然后我们面对的是 ,然后用 将 除成 ,这个时候,,且 ,并且得构造出 .
根据辗转相除法,我们有
$$\gcd(a,b)=g \Rightarrow gcd(h\times b^j+r,b)=\gcd(r,b)=g $$如果设 ,考虑最简单的情况,,我们一定能够保证 ,这样似乎合法?
然后,你会发现你错了,举个栗子:当 时,我们可以构造出 ,但是 ,那么问题出在哪里?我们还有个前提条件是 ,得保证这个,我们才能构造出正确的答案。
也就是说,如果 给得不够好,就没有答案咯?那为什么题目 “可以证明” 存在 ?事实上, 只是我猜测的其中一种情况, 不一定一定就是 ,我们可以记 ,保证 即可,即, 即可。
至于如何找到这个 ,由于我们有
$$h^k\le gi<2h^k \Rightarrow {h^k\over g}\le i<{2h^k\over g} $$因为这个 是个整数,我们只需要找到一个 ,满足区间 包含至少一个整数即可,一个一定满足条件的不等式是
只需要找到这个 就可以了,取 ,而 .
但是值得注意的是,直接取 的同时,我们一定有 ,因为 ,但是至于为什么必须保证 呢?因为我们的 ,在此我们取 ,则需保证 ,显然,当 时不等式不成立,但是我们取上取整保证了 .
总复杂度 .
题解过于简单,直接给出构造方法:
$$b=g\left\lceil{h^K\over g}\right\rceil,a=hb+g\quad(g<h^K) $$我只能说,这个构造方法没有时间还真想不到,或许只有 和 可以直接出吧?
叁、参考代码 ¶
#include<cstdio> #include<algorithm> #include<cstdlib> #include<cstring> #include<cmath> #include<vector> using namespace std; // #define NDEBUG #include<cassert> namespace Elaina{ #define rep(i, l, r) for(int i=(l), i##_end_=(r); i<=i##_end_; ++i) #define drep(i, l, r) for(int i=(l), i##_end_=(r); i>=i##_end_; --i) #define fi first #define se second #define mp(a, b) make_pair(a, b) #define Endl putchar('\n') #define mmset(a, b) memset(a, b, sizeof a) // #define int long long typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; typedef pair<ll, ll> pll; template<class T>inline T fab(T x){ return x<0? -x: x; } template<class T>inline void getmin(T& x, const T rhs){ x=min(x, rhs); } template<class T>inline void getmax(T& x, const T rhs){ x=max(x, rhs); } template<class T>inline T readin(T x){ x=0; int f=0; char c; while((c=getchar())<'0' || '9'<c) if(c=='-') f=1; for(x=(c^48); '0'<=(c=getchar()) && c<='9'; x=(x<<1)+(x<<3)+(c^48)); return f? -x: x; } template<class T>inline void writc(T x, char s='\n'){ static int fwri_sta[1005], fwri_ed=0; if(x<0) putchar('-'), x=-x; do fwri_sta[++fwri_ed]=x%10, x/=10; while(x); while(putchar(fwri_sta[fwri_ed--]^48), fwri_ed); putchar(s); } } using namespace Elaina; ull R(ull a, ull b){ if(a<b) return R(b, a); if(b==1) return a; return R(a/b, b); } ull gcd(ull a, ull b){ return b? gcd(b, a%b): a; } ull g, h, k, tmp, i, a, b; signed main(){ freopen("euklid.in", "r", stdin); freopen("euklid.out", "w", stdout); rep(_, 1, readin(1)){ g=readin(1llu), h=readin(1llu); tmp=1, k=0; while(g>=tmp) ++k, tmp*=h; // When x,y are integers the equation ceil(x/y)=(x+y-1)/y is established i=(tmp+g-1)/g, b=g*i, a=h*b+g; writc(a, ' '), writc(b); } return 0; }
- 1
信息
- ID
- 6350
- 时间
- 1000ms
- 内存
- 500MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者