当前位置: 首页 > news >正文

裴蜀定理扩展欧几里得定理

裴蜀定理(又称贝祖定理)

理论

一定存在整数 x , y x, y x,y,满足 a x + b y = g c d ( a , b ) ax + by = gcd(a, b) ax+by=gcd(a,b)

4 x + 6 y = 2 4x + 6y = 2 4x+6y=2,有整数解 x = − 1 , y = 1 x = -1, y = 1 x=1,y=1
4 x + 6 y = 3 4x + 6y = 3 4x+6y=3,即 x = 3 − 6 y 4 x = \frac{3 - 6y}{4} x=436y 无整数解。

证明:

设取整数 x 0 , y 0 x_0, y_0 x0,y0 时, a x + b y ax + by ax+by 的最小正整数为 s s s

a x 0 + b y 0 = s ax_0 + by_0 = s ax0+by0=s

g c d ( a , b ) ∣ a x 0 gcd(a, b) \mid ax_0 gcd(a,b)ax0 g c d ( a , b ) ∣ b y 0 gcd(a, b) \mid by_0 gcd(a,b)by0

g c d ( a , b ) ∣ s ⋯ ⋯ ( 1 ) gcd(a, b) \mid s \cdots\cdots (1) gcd(a,b)s⋯⋯(1)

a = q s + r ( 0 ≤ r < s ) a = qs + r (0 \leq r < s) a=qs+r(0r<s)

r = a − q s r = a - qs r=aqs

= a − q ( a x 0 + b y 0 ) = a - q(ax_0 + by_0) =aq(ax0+by0)

= a ( 1 − q x 0 ) + b ( − q y 0 ) = a(1 - qx_0) + b(-qy_0) =a(1qx0)+b(qy0)

= a x + b y = ax + by =ax+by

s s s 是最小正整数,故 r = 0 r = 0 r=0

所以 s ∣ a s \mid a sa,同理 s ∣ b s \mid b sb
s ∣ g c d ( a , b ) ⋯ ⋯ ( 2 ) s \mid gcd(a, b) \cdots\cdots (2) sgcd(a,b)⋯⋯(2)

( 1 ) ( 2 ) (1)(2) (1)(2) s = g c d ( a , b ) s = gcd(a, b) s=gcd(a,b)。证毕。

裴蜀定理推广
一定存在整数 x , y x, y x,y,满足 a x + b y = g c d ( a , b ) × n ax + by = gcd(a, b) \times n ax+by=gcd(a,b)×n

4 x + 6 y = 8 4x + 6y = 8 4x+6y=8,有整数解 x = − 4 , y = 4 x = -4, y = 4 x=4,y=4

裴蜀定理再推广
一定存在整数 X 1 ⋯ X i X_1 \cdots X_i X1Xi,满足 ∑ i = 1 n A i X i = g c d ( A 1 , A 2 , ⋯   , A n ) \sum_{i = 1}^{n} A_iX_i = gcd(A_1, A_2, \cdots, A_n) i=1nAiXi=gcd(A1,A2,,An)

4 x 1 + 6 x 2 + 2 x 3 = 4 4x_1 + 6x_2 + 2x_3 = 4 4x1+6x2+2x3=4,有整数解 x 1 = 1 , x 2 = 0 , x 3 = 0 x_1 = 1, x_2 = 0, x_3 = 0 x1=1,x2=0,x3=0

裴蜀定理扩展
a x + b y = n ax + by = n ax+by=n

结论:

  • n > a b − a − b n > ab - a - b n>abab,有解
  • n = 0 n = 0 n=0,有解
  • n < 0 n < 0 n<0,无解
  • a x + b y = n ax + by = n ax+by=n 有解,则 a x + b y = a b − a − b − n ax + by = ab - a - b - n ax+by=ababn 无解

注意

欧几里得算法求 g c d ( a , b ) gcd(a, b) gcd(a,b)

如果代入负数,结果会返回负数

例: g c d ( 8 , − 4 ) = − 4 gcd(8, -4) = -4 gcd(8,4)=4

如果系数 A i A_i Ai 为负数,

g c d gcd gcd 时可代入其绝对值,

确保所求最大公约数为正数,

这样并不会影响解的存在。

例题

P4549 【模板】裴蜀定理

题目描述
给定一个包含 n n n 个元素的整数序列 A A A,记作 A 1 , A 2 , A 3 , . . . , A n A_1,A_2,A_3,...,A_n A1,A2,A3,...,An
求另一个包含 n n n 个元素的待定整数序列 X X X,记 S = ∑ i = 1 n A i × X i S=\sum\limits_{i=1}^nA_i\times X_i S=i=1nAi×Xi,使得 S > 0 S>0 S>0 S S S 尽可能的小。

输入格式
第一行一个整数 n n n,表示序列元素个数。
第二行 n n n 个整数,表示序列 A A A

输出格式
一行一个整数,表示 S > 0 S>0 S>0 的前提下 S S S 的最小值。

输入输出样例 #1
输入 #1

2
4059 -1782

输出 #1

99

说明/提示
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 20 1 \le n \le 20 1n20 ∣ A i ∣ ≤ 1 0 5 |A_i| \le 10^5 Ai105,且 A A A 序列不全为 0 0 0

#include<bits/stdc++.h>
using namespace std;
int gcd(int a, int b)
{
	return b ? gcd(b, a % b) : a;
}
int main()
{
	int n, ans;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		int x;
		cin >> x;
		if (i == 1)
		{
			ans = abs(x);
		}
		else
		{
			ans = gcd(ans, abs(x));
		}
	}
	cout << ans;
	return 0;
}

买不到的数目

题目描述
小明开了一家糖果店。他别出心裁:把水果糖包成 4 颗一包和 7 颗一包的两种。糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是 17。大于 17 的任何数字都可以用 4 和 7 组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
输入描述
输入两个正整数,表示每种包装中糖的颗数(都不多于 1000 )。
输出描述

输出一个正整数,表示最大不能买到的糖数。
不需要考虑无解的情况
输入输出样例
示例
输入

4 7

输出

17
#include <iostream>
using namespace std;
int x, y;
int main()
{
    cin >> x >> y;
    cout << x * y - x - y << endl;
    return 0;
}

扩展欧几里得算法

理论

问题1:

a x + b y = g c d ( a , b ) ax + by = gcd(a, b) ax+by=gcd(a,b) 的一组整数解

b = 0 b = 0 b=0 a x + b y = a ax + by = a ax+by=a 故而 x = 1 , y = 0 x = 1, y = 0 x=1,y=0
b ≠ 0 b \neq 0 b=0
由欧几里得算法, g c d ( a , b ) = g c d ( b , a % b ) gcd(a, b) = gcd(b, a\%b) gcd(a,b)=gcd(b,a%b)
由裴蜀定理,
g c d ( a , b ) = a x + b y gcd(a, b) = ax + by gcd(a,b)=ax+by
g c d ( b , a % b ) = b x 1 + ( a % b ) y 1 gcd(b, a\%b) = bx_1 + (a\%b)y_1 gcd(b,a%b)=bx1+(a%b)y1
= b x 1 + ( a − ⌊ a b ⌋ × b ) y 1 = bx_1 + (a - \lfloor\frac{a}{b}\rfloor\times b)y_1 =bx1+(aba×b)y1
= a y 1 + b ( x 1 − a b y 1 ) = ay_1 + b(x_1 - \frac{a}{b}y_1) =ay1+b(x1bay1)

所以 x = y 1 x = y_1 x=y1 y = x 1 − a b y 1 y = x_1 - \frac{a}{b}y_1 y=x1bay1
可以用递归算法,先求出下一层的 x 1 , y 1 x_1, y_1 x1,y1,再回代到上一层,层层回代,可求特解 ( x 0 , y 0 ) (x_0, y_0) (x0,y0)

构造通解
{ x = x 0 + b g c d ( a , b ) ∗ k y = y 0 − a g c d ( a , b ) ∗ k \begin{cases} x = x_0 + \frac{b}{gcd(a, b)}*k \\ y = y_0 - \frac{a}{gcd(a, b)}*k \end{cases} {x=x0+gcd(a,b)bky=y0gcd(a,b)ak (考虑 a x + b y = 0 ax + by = 0 ax+by=0 构造)

例: 8 x + 6 y = 2 8x + 6y = 2 8x+6y=2,解: ( 1 , − 1 ) , ( 4 , − 5 ) , ( 7 , − 9 ) ⋯ (1, -1), (4, -5), (7, -9)\cdots (1,1),(4,5),(7,9)

//欧几里得算法
int gcd(int a, int b) {
	if (b == 0) {
		return 0;
	}
	return gcd(b, a % b);
}
int exgcd(int a, int b, int& x, int& y) {
	if (b == 0) {
		int x = 1, y = 0;
		return a;
	}
	int x1, y1, d;
	d = exgcd(b, a % b, x1, y1);
	x = y1, y = x1 - a / b * y1;
	return d;
}

问题2:

求不定方程 a x + b y = c ax + by = c ax+by=c 的一组整数解

  1. g c d ( a , b ) ∣ c gcd(a, b) \mid c gcd(a,b)c,则有整数解
    • 先用扩欧算法求 a x + b y = g c d ( a , b ) ax + by = gcd(a, b) ax+by=gcd(a,b) 的解
    • 再乘以 c / g c d ( a , b ) c / gcd(a, b) c/gcd(a,b),即得原方程的特解 ( x 0 , y 0 ) (x_0, y_0) (x0,y0)
    • 例: 8 x + 6 y = 6 8x + 6y = 6 8x+6y=6,解得 x = 3 , y = − 3 x = 3, y = -3 x=3,y=3

构造通解
{ x = x 0 + b g c d ( a , b ) ∗ k y = y 0 − a g c d ( a , b ) ∗ k \begin{cases} x = x_0 + \frac{b}{gcd(a, b)}*k \\ y = y_0 - \frac{a}{gcd(a, b)}*k \end{cases} {x=x0+gcd(a,b)bky=y0gcd(a,b)ak (考虑 a x + b y = 0 ax + by = 0 ax+by=0 构造)

  1. g c d ( a , b ) ∤ c gcd(a, b) \nmid c gcd(a,b)c,则无整数解。
    • 例: 8 x + 6 y = 3 8x + 6y = 3 8x+6y=3 x = 3 − 6 y 8 x = \frac{3 - 6y}{8} x=836y
#include<bits/stdc++.h>
using namespace std;
int exgcd(int a, int b, int& x, int& y) {
	if (b == 0) {
		x = 1, y = 0;
		return a;
	}
	int x1, y1, d;
	d = exgcd(b, a % b, x1, y1);
	x = y1;
	y = x1 - a / b * y1;
	return d;
}
int main() {
	int a, b, c, x, y;
	cin >> a >> b >> c;
	int d = exgcd(a, b, x, y);
	if (c % d == 0) {
		printf("%d %d", c / d * x, c / d * y);
	}
	else {
		puts("none");
	}
	return 0;
}

相关文章:

  • ssh密钥连接远程服务器并用scp传输文件
  • QAI AppBuilder 快速上手(8): 图像修复应用实例2
  • 网络带宽测速工具选择指南iperf3 nttcp tcpburn jperf使用详解
  • Vue 3 的<Teleport>功能与用法
  • 代码随想录算法训练营第十二天
  • 【ES系列】Elasticsearch从入门到精通保姆级教程 | 启篇
  • Java9新特性
  • Python 并发编程指南:协程 vs 多线程及其他模型比较
  • SpringBoot集成RedisSearch
  • 深度学习|注意力机制
  • 【Java中级】11章、注解、元注解介绍、快速入门,了解java注解的基本使用方式【2】
  • vscode 跳转失败之c_cpp_properties.json解析
  • 【从一个 TypeScript 报错理解 ES6 模块的三种导入方式】
  • 北京自在科技:让万物接入苹果Find My网络的″钥匙匠″
  • sql-labs靶场 less-2
  • PyTorch张量范数计算终极指南:从基础到高阶实战
  • Python: sqlite3.OperationalError: no such table: ***解析
  • 在1panel中安装WebUI
  • 未来杭州:科技与诗意的时空交响曲
  • Linux 学习笔记(4):cd 与 pwd 命令的深度解析与实战应用(期末、期中复习必备)