1 条题解

  • 0
    @ 2025-8-24 22:27:11

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 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} $$

    给定 g,hg,h,请找到 a,ba,b 使得 gcd(a,b)=gR(a,b)=h\gcd(a,b)=g∧R(a,b)=h. 保证 g,h200000g,h\le 200000,可以证明,存在 a,b1018a,b\le 10^{18} 的解。

    贰、题解

    显然一道构造题,但是挺难想到。下面我们不妨假设 aba\ge b.

    首先想到的就是去考察 RR 的性质,如果你打表,你会发现......不,你什么都发现不了。

    但是我们可以利用人类智慧,首先一定有 R(h,hk)=hR(h,h^k)=h,更一般地,有 R(h,hk+r)=hR(h,h^k+r)=h,我们只需要保证 r<hkr<h^k 即可。

    也即,有 R(h,x)=h(x[hk,2hk))R(h,x)=h\Big(x\in [h^k,2h^k)\Big),如果我们不考虑 gcd\gcd 的限制,那么我们可以直接构造 a=hk,b=ha=h^k,b=h,但是像这样由一边除到尽头,我们始终需要强制让一边为 hh,如 b=hb=h,而此时我们是万般不能让 gcd(a,b)=g\gcd(a,b)=g 的(除了可能存在的一些特殊情况)。所以,这种 “一边除到底” 好是好,但是不能满足所有条件。

    但是我们可以考虑,当 a/ba/b 完之后,得到 a=ha'=h,然后我们面对的是 R(a,b)=R(h,b)R(a',b)=R(h,b),然后用 hhbb 除成 11,这个时候,a=h×bj+r(r<bj)a=h\times b^j+r(r<b^j),且 b[hk,2hk)b\in[h^k,2h^k),并且得构造出 gcd(a,b)=g\gcd(a,b)=g.

    根据辗转相除法,我们有

    $$\gcd(a,b)=g \Rightarrow gcd(h\times b^j+r,b)=\gcd(r,b)=g $$

    如果设 b=ghb=gh,考虑最简单的情况,r=gj=1a=h2g+g=g(h2+1)r=g∧j=1\Rightarrow a=h^2g+g=g(h^2+1),我们一定能够保证 gcd(h,h2+1)=1\gcd(h,h^2+1)=1,这样似乎合法?

    然后,你会发现你错了,举个栗子:当 g=2,h=3g=2,h=3 时,我们可以构造出 a=20,b=6a=20,b=6,但是 R(20,6)=2R(20,6)=2,那么问题出在哪里?我们还有个前提条件是 gh[hk,2hk)g[hk1,2hk1)gh\in [h^k,2h^k)\Rightarrow g\in[h^{k-1},2h^{k-1}),得保证这个,我们才能构造出正确的答案。

    也就是说,如果 gg 给得不够好,就没有答案咯?那为什么题目 “可以证明” 存在 a,b1018a,b\le 10^{18}?事实上,b=ghb=gh 只是我猜测的其中一种情况,bb 不一定一定就是 ghgh,我们可以记 b=gib=gi,保证 b=gi[hk,2hk)b=gi\in [h^k,2h^k) 即可,即,g[hki,2hki)g\in\left[{h^k\over i},{2h^k\over i}\right) 即可。

    至于如何找到这个 ii,由于我们有

    $$h^k\le gi<2h^k \Rightarrow {h^k\over g}\le i<{2h^k\over g} $$

    因为这个 ii 是个整数,我们只需要找到一个 kk,满足区间 [hkg,2hkg)\left[{h^k\over g},{2h^k\over g}\right) 包含至少一个整数即可,一个一定满足条件的不等式是

    hkg+1<2hkgg<hk{h^k\over g}+1<{2h^k\over g} \Rightarrow g<h^k

    只需要找到这个 kk 就可以了,取 i=hkgi=\left\lceil{h^k\over g}\right\rceil,而 a=h×b+ga=h\times b+g.

    但是值得注意的是,直接取 i=hkgi=\left\lceil{h^k\over g}\right\rceil 的同时,我们一定有 i>1i>1,因为 g<hkg<h^k,但是至于为什么必须保证 i>1i>1 呢?因为我们的 a=h×bj+r(r<bj)a=h\times b^j+r(r<b^j),在此我们取 j=1j=1,则需保证 r=g<b=gir=g<b=gi,显然,当 i=1i=1 时不等式不成立,但是我们取上取整保证了 i>1i>1.

    总复杂度 O(Tloghg)\mathcal O(T\log_hg).

    题解过于简单,直接给出构造方法:

    $$b=g\left\lceil{h^K\over g}\right\rceil,a=hb+g\quad(g<h^K) $$

    我只能说,这个构造方法没有时间还真想不到,或许只有 SYDevil\sf SYDevilOID\sf OID 可以直接出吧?

    叁、参考代码 ¶

    #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
    上传者