裴蜀定理
裴蜀定理內容:對於\(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;
}