与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\),求解成功。

浙公网安备 33010602011771号