裴蜀定理应用
裴蜀定理
- 什么是裴蜀定理
- 裴蜀定理的简单证明
- 裴蜀定理推论
- 题目洛谷P4549 【模板】裴蜀定理
- 题目描述
- 输入格式
- 输出格式
- 输入输出样例 #1
- 输入 #1
- 输出 #1
- 说明/提示
- 题目分析
- 参考代码
什么是裴蜀定理
对于不全为0的整数a,b,一定存在整数x,y,满足ax+by=gcd(a,b)对于不全为0的整数a,b,一定存在整数x,y,满足ax+by=gcd(a,b)对于不全为0的整数a,b,一定存在整数x,y,满足ax+by=gcd(a,b)
就比如2x+6y=82x+6y=82x+6y=8就有解,比如x=1,y=1或者x=4,y=0x=1,y=1或者x=4,y=0x=1,y=1或者x=4,y=0
而2x+6y=12x+6y=12x+6y=1,就找不到对应的一组整数解
裴蜀定理的简单证明
设有整数x0,y0x_0,y_0x0,y0,ax+byax+byax+by为最小正整数结果为ccc,即
ax0+by0=cax_0+by_0=cax0+by0=c
因为有
gcd(a,b)∣ax0,gcd(a,b)∣by0gcd(a,b)|ax_0,gcd(a,b)|by_0gcd(a,b)∣ax0,gcd(a,b)∣by0
所以
gcd(a,b)∣c(1)gcd(a,b)|c {\hspace{2em}} (1)gcd(a,b)∣c(1)
不妨设
a=kc+r(0≤r<c)a=kc+r(0 \le r < c)a=kc+r(0≤r<c)
就有
r=a−kc=a−k(ax0+by0)=a(1−kx0)+b(−ky0)=ax+by\ \begin {array}{rcl} r & = & a - kc \\ & = & a - k(ax_0 + by_0) \\ & = & a(1 - kx_0) + b(-ky_0) \\ & = & ax + by \end {array} \ r====a−kca−k(ax0+by0)a(1−kx0)+b(−ky0)ax+by
因为sss是最小的正整数,所以r=0r=0r=0
所以s∣a,同理s∣bs|a,同理s|bs∣a,同理s∣b
所以
s∣gcd(a,b)(2)s|gcd(a,b) {\hspace{2em}} (2)s∣gcd(a,b)(2)
由(1),(2)(1),(2)(1),(2)可证s=gcd(a,b)s=gcd(a,b)s=gcd(a,b)
裴蜀定理推论
- 对于ax+by=cax+by=cax+by=c,如果c满足gcd(a,b)∣cc满足 gcd(a,b)|cc满足gcd(a,b)∣c,那么该方程就有整数解,即
线性方程𝑎𝑥+𝑏𝑦=𝑐有整数解,当且仅当gcd(𝑎,𝑏)∣𝑐线性方程 𝑎𝑥+𝑏𝑦=𝑐 有整数解,当且仅当 gcd(𝑎,𝑏)∣𝑐线性方程ax+by=c有整数解,当且仅当gcd(a,b)∣c - 一定存在整数X1⋯XiX_1 \cdots X_iX1⋯Xi,满足
∑i=1nAiXi=gcd(A1,A2,A3⋯An)\sum_{i=1}^n A_iX_i=gcd(A_1,A_2,A_3 \cdots A_n)i=1∑nAiXi=gcd(A1,A2,A3⋯An)
如果有负数,可以加上绝对值,不会影响最终结果
题目洛谷P4549 【模板】裴蜀定理
题目描述
给定一个包含 nnn 个元素的整数序列 AAA,记作 A1,A2,A3,...,AnA_1,A_2,A_3,...,A_nA1,A2,A3,...,An。
求另一个包含 nnn 个元素的待定整数序列 XXX,记 S=∑i=1nAi×XiS=\sum\limits_{i=1}^nA_i\times X_iS=i=1∑nAi×Xi,使得 S>0S>0S>0 且 SSS 尽可能的小。
输入格式
第一行一个整数 nnn,表示序列元素个数。
第二行 nnn 个整数,表示序列 AAA。
输出格式
一行一个整数,表示 S>0S>0S>0 的前提下 SSS 的最小值。
输入输出样例 #1
输入 #1
2
4059 -1782
输出 #1
99
说明/提示
对于 100%100\%100% 的数据,1≤n≤201 \le n \le 201≤n≤20,∣Ai∣≤105|A_i| \le 10^5∣Ai∣≤105,且 AAA 序列不全为 000。
题目分析
这个的本质就是求所有系数的最大公约数,可以从上文的裴蜀定理的推论知道
参考代码
#include<bits/stdc++.h>
using namespace std;
using ll =long long ;const int N=1e6;int gcd(int a,int b){return b?gcd(b,a%b):a;
}int main(){int n;cin>>n;int s=0;for(int i=1;i<=n;i++){int a;cin>>a;s=gcd(s,abs(a));}cout<<s;
}