与gcd有关的

一、欧几里得算法

i64 gcd(i64 a, i64 b) { return b == 0LL ? a : gcd(b, a % b); }

二、更相相减法

i64 gcd(i64 a, i64 b) {
    if (a == 0) return a;
    if (b == 0) return b;
    
    i64 a_len = std::countr_zero(a);
    i64 b_len = std::countr_zero(b);
    a >>= a_len;
    while (true) {
        b >>= b_len;
        if (a > b) swap(a, b);
        b -= a;
        if (b == 0) break;
        b_len = std::countr_zero(b);
    }
    return a << min(a_len, b_len);
}

三、推广

我们可以通过 \(x+y=n\)\(lcm(x,y)=k\) 推出 \(x\)\(y\)

推导:

\(gcd(x,y)=d\),可以得到 \(gcd(x+y,y)=gcd(x,x+y)=gcd(x,y)=d\),即 \(gcd(x,n)=gcd(n,y)=d\)

\(lcm(x,y)=k\),可以推出 \(lcm(x,y)=\frac{xy}{gcd(x,y)}=k\),然后 \(xy=kd\)

又因为 \((x+y)^2=n^2 \Rightarrow (x-y)^2=(x+y)^2-4xy=n^2-4kd\)

可以发现我们只需要求出 \(d\),就可以得到 \(x,y\) 的值。

我们令 \(gcd(k,n)=d' \Rightarrow gcd(\frac{xy}{d},n)=d'\),由于 \(gcd(y,n)=d\),所以让等式两边同时除以 \(d\),得到 \(gcd(\frac{xy}{d^2},\frac{n}{d})=\frac{d'}{d}\)

我们已知 \(gcd(\frac{x}{d},\frac{y}{d})=1 \Rightarrow gcd(\frac{x}{d},\frac{n}{d})=gcd(\frac{y}{d},\frac{n}{d})=1\),所以我们可以得到上面的式子可以转化为:\(gcd(\frac{xy}{d^2},\frac{n}{d})=\frac{d'}{d}=1 \Rightarrow d'=d\),所以 \(gcd(k,n)=d\),求解成功。

posted @ 2024-08-31 17:52  grape_king  阅读(23)  评论(0)    收藏  举报