裴蜀定理(又称贝祖定理)证明过程 及其部分推广 洛谷4549 c++题解 算法竞赛常用数论知识
裴蜀定理(又称贝祖定理)证明过程
对于任意整数 a, b,存在整数 x, y,使得:
ax+by=gcd(a,b) a x + b y = \gcd(a, b) ax+by=gcd(a,b)
示例:
- 例如,对于方程 4x + 6y = 2,存在整数解 x = -1, y = 1。
- 而方程 4x + 6y = 3 则无整数解。
证明:
设 S 为形如 ax + by 的最小正整数,即:
S=ax0+by0 S = a x_0 + b y_0 S=ax0+by0
其中 x0,y0x_0, y_0x0,y0 为整数。
由于 gcd(a,b)∣a\gcd(a, b) \mid agcd(a,b)∣a 且 gcd(a,b)∣b\gcd(a, b) \mid bgcd(a,b)∣b,因此:
gcd(a,b)∣ax0且gcd(a,b)∣by0 \gcd(a, b) \mid a x_0 \quad \text{且} \quad \gcd(a, b) \mid b y_0 gcd(a,b)∣ax0且gcd(a,b)∣by0
于是:
gcd(a,b)∣S⋯⋯(1) \gcd(a, b) \mid S \quad \cdots \cdots (1) gcd(a,b)∣S⋯⋯(1)
接下来,我们考虑整数除法:
设 a=qS+ra = q S + ra=qS+r,其中 0≤r<S0 \leq r < S0≤r<S,则:
r=a−qS=a−q(ax0+by0)=a(1−qx0)+b(−qy0) \begin{aligned} r &= a - q S \\ &= a - q(a x_0 + b y_0) \\ &= a(1 - q x_0) + b(-q y_0) \end{aligned} r=a−qS=a−q(ax0+by0)=a(1−qx0)+b(−qy0)
注意到 rrr 也可以表示为 ax+bya x + b yax+by 的形式,而 SSS 是形如 ax+bya x + b yax+by 的最小正整数,因此必有 r=0r = 0r=0。这说明 S∣aS \mid aS∣a。
同理可证 S∣bS \mid bS∣b。
因此,SSS 是 aaa 和 bbb 的公约数,即:
S∣gcd(a,b)⋯⋯(2) S \mid \gcd(a, b) \quad \cdots \cdots (2) S∣gcd(a,b)⋯⋯(2)
由 (1) 和 (2) 可知:
S=gcd(a,b) S = \gcd(a, b) S=gcd(a,b)
证毕。
裴蜀定理推广
存在整数 x,yx, yx,y,使得:
ax+by=gcd(a,b)⋅n a x + b y = \gcd(a, b) \cdot n ax+by=gcd(a,b)⋅n
示例:
4x+6y=8,整数解为 x=−4, y=4 4x + 6y = 8,\quad \text{整数解为 } x = -4,\ y = 4 4x+6y=8,整数解为 x=−4, y=4
裴蜀定理再推广
存在整数 X1,X2,…,XnX_1, X_2, \dots, X_nX1,X2,…,Xn,使得:
∑i=1nAiXi=gcd(A1,A2,…,An) \sum_{i=1}^{n} A_i X_i = \gcd(A_1, A_2, \dots, A_n) i=1∑nAiXi=gcd(A1,A2,…,An)
示例:
4x1+6x2+2x3=4,整数解为 x1=1, x2=0, x3=0 4x_1 + 6x_2 + 2x_3 = 4,\quad \text{整数解为 } x_1 = 1,\ x_2 = 0,\ x_3 = 0 4x1+6x2+2x3=4,整数解为 x1=1, x2=0, x3=0
注意事项
- 若代入负数,欧几里得算法可能返回负数结果:
gcd(8,−4)=−4 \gcd(8, -4) = -4 gcd(8,−4)=−4
- 若系数为负数,可取绝对值计算最大公约数,不影响解的存在性:
gcd(∣A1∣,∣A2∣,…,∣An∣) \gcd(|A_1|, |A_2|, \dots, |A_n|) gcd(∣A1∣,∣A2∣,…,∣An∣)
Luogu P4549 【模板】裴蜀定理
题目描述
给定一个包含 nnn 个元素的整数序列 AAA,记作:
A1,A2,…,An A_1, A_2, \dots, A_n A1,A2,…,An
求另一个包含 nnn 个元素的待定整数序列 XXX,记:
S=∑i=1nAi×Xi S = \sum_{i=1}^{n} A_i \times X_i S=i=1∑nAi×Xi
使得 S>0S > 0S>0 且 SSS 尽可能的小。
输入格式
第一行一个整数 nnn,表示序列元素个数。
第二行 nnn 个整数,表示序列 AAA。
输出格式
一行一个整数,表示在 S>0S > 0S>0 的前提下,SSS 的最小值。
数据范围
- 1≤n≤201 \leq n \leq 201≤n≤20
- ∣Ai∣≤105|A_i| \leq 10^5∣Ai∣≤105
- 序列 AAA 不全为 000
思路:正如上面证明过程,只需要求解所有系数的最大公约数
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}
void solve()
{
int n, a, s;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a;
s = gcd(s, abs(a));
}
cout << s;
}
更多推荐



所有评论(0)