1. 程式人生 > 其它 >裴蜀定理

裴蜀定理

裴蜀定理

裴蜀定理內容:對於\(a,b\)是不為零的整數,存在\(x,y\),使得\(ax+by=k*gcd(a,b)\)

特別注意對於這個定理必須限制\(a,b,x,y\)為整數。


證明過程比較毒瘤,不過看看也是挺好理解的,可以自行上網。


裴蜀定理擴充套件

我們直接說常見的應用,基本上不會直接用原定理,一般都是用擴充套件多一些。

擴充套件到多項式

首先裴蜀定理可以擴充套件到多項式,比如洛谷上的模板題

題目描述

給定一個包含 \(n\) 個元素的整數序列\(A\),記作\(A1,A2,A3,...,An\)

求另一個包含 \(n\)​ 個元素的待定整數序列 \(X\)​,記$ S=\sum_{i=1}^nA_i \times X_i$​​,使得 S>0 且 S 儘可能的小。

輸入格式

第一行一個整數 \(n\),表示序列元素個數。

第二行 \(n\) 個整數,表示序列 \(A\)

輸出格式

一行一個整數,表示 S>0 的前提下 S 的最小值。

輸入輸出樣例

輸入 #1

2
4059 -1782

輸出 #1

99

說明/提示

對於 100%的資料,\(1≤n≤20,∣Ai∣≤10^5\),且 A 序列不全為 0。

裴蜀定理可以擴充套件到多項式所以$ S=\sum_{i=1}^nA_i \times X_i=gcd(A_i)\times k\(很顯然因為\)S\(為\)A_i\(的公因數的倍數,所以當\)k=1\(時多項式最小,只需要一直列舉\)A_i\(取公因數​​即可,注意\)

A_i$需要用絕對值。

#include<bits/stdc++.h>
using namespace std;
int n,ans;
inline int gcd(int x,int y){return y?gcd(y,x%y):x;}
int main(){
	scanf("%d%d",&n,&ans);
	for(int i=2,x;i<=n;++i){scanf("%d",&x),ans=gcd(ans,abs(x));}
	printf("%d\n",ans);return 0;}

另外一種擴充套件

還是\(ax+by=n\),其中\(a,b\)

互相為素數。

其中 x 和 y 為自然數。如果方程有解,稱 n 可以被 a、b 表示。

\(C=ab-a-b\) 。由 a 與 b 互素,C 必然為奇數。則有結論:

對任意的整數 n,n 與\(C-n\)中有且僅有一個可以被表示。

即:可表示的數與不可表示的數在區間\([0,C]\) 對稱(關於 C 的一半對稱)。0 可被表示,C 不可被表示;負數不可被表示,大於 C 的數可被表示。

[NOIP2017 提高組] 小凱的疑惑 / [藍橋杯 2013 省] 買不到的數目

很簡單的一道結論題。

#include<bits/stdc++.h>
using namespace std;
long long a,b;

int main(){
    scanf("%lld%lld",&a,&b);
    printf("%lld\n",a*b-a-b);
    return 0;
}