大家好,欢迎来到IT知识分享网。
裴蜀定理:对于整数 a , b a,b a,b,若 a , b a,b a,b 不全为0,则存在 x , y x,y x,y 使得 a × x + b × y = gcd(a,b) a \times x + b \times y = \text{gcd(a,b)} a×x+b×y=gcd(a,b)。
不失一般性,设 0 ≤ a ≤ b 0 \le a \le b 0≤a≤b,对于 a < 0 a<0 a<0 则将 − a , b {-a,b} −a,b 的解的 x x x 取反, b < 0 b<0 b<0 同理。
如: a = 3 , b = 2 {a=3,b=2} a=3,b=2 的一种解为 x = 3 , y = − 4 {x=3,y=-4} x=3,y=−4,那么 a = − 3 , b = 2 {a=-3,b=2} a=−3,b=2 的一组解就是 − 3 , − 4 {-3,-4} −3,−4。
s t 1 : a = 0 , gcd ( a , b ) = b st_1:a=0,\text{gcd}(a,b)=b st1:a=0,gcd(a,b)=b
此时取 x = 0 , y = 1 x=0,y=1 x=0,y=1 则 a × x + b × y = b = gcd ( a , b ) a \times x+b \times y=b=\text{gcd}(a,b) a×x+b×y=b=gcd(a,b),条件成立。
s t 2 : a ≠ 0 , gcd ( a , b ) = 0 st_2:a \neq 0,\text{gcd}(a,b)=0 st2:a=0,gcd(a,b)=0
设 v = b % a v=b\%a v=b%a 即 v = b − t × v v=b-t \times v v=b−t×v 其中 t = ⌊ a / b ⌋ t=\lfloor a/b \rfloor t=⌊a/b⌋。
证明:存在 k ( 1 ≤ k ≤ a ) k(1 \le k \le a) k(1≤k≤a) 使得 ( k × v ) % a = 1 (k \times v) \% a=1 (k×v)%a=1
先证明:对于 k ( 1 ≤ k ≤ a ) k(1 \le k \le a) k(1≤k≤a) 不存在 t t t 使得 ( t × v ) % a = ( k × v ) % a (t \times v)\%a=(k \times v)\%a (t×v)%a=(k×v)%a,其中 ( t < k ) (t<k) (t<k)。
问题可转化为:证明 不存在 t t t 使得 t % a = k % a t \%a=k\%a t%a=k%a, ( t < k ) (t<k) (t<k)。
运用 我今天刚学的 反证法:
设 t % a = b t\%a=b t%a=b
若 b ≠ 0 b\neq 0 b=0,则 k = b + m × a , ( m ≠ 1 ) k=b+m\times a,(m\neq1) k=b+m×a,(m=1)。
所以 m < 1 m<1 m<1 或 m > a m>a m>a,矛盾。
若 b = 0 b=0 b=0,则 t = a t=a t=a。
因为 k > t k>t k>t,所以 k > a k>a k>a,矛盾。
所以,对于 k ( 1 ≤ k ≤ a ) k(1 \le k \le a) k(1≤k≤a) 不存在 t t t 使得 ( t × v ) % a = ( k × v ) % a (t \times v)\%a=(k \times v)\%a (t×v)%a=(k×v)%a,其中 ( t < k ) (t<k) (t<k)。
因为:对于 k ( 1 ≤ k ≤ a ) k(1 \le k \le a) k(1≤k≤a) 不存在 t t t 使得 ( t × v ) % a = ( k × v ) % a , ( t < k ) (t \times v)\%a=(k \times v)\%a,(t<k) (t×v)%a=(k×v)%a,(t<k)。
所以, ( k × v ) % a (k \times v)\%a (k×v)%a 包含了 0 ∼ a − 1 0 \sim a-1 0∼a−1 的所有数。
所以, ( k × v ) % a (k \times v)\%a (k×v)%a 包含 1 1 1。
所以 ,存在 k ( 1 ≤ k ≤ a ) k(1 \le k \le a) k(1≤k≤a) 使得 ( k × v ) % a = 1 (k \times v) \% a=1 (k×v)%a=1
所以,存在 k ( 1 ≤ k ≤ a ) k(1 \le k \le a) k(1≤k≤a) 使得 k × b − ⌊ ( k × b ) / a ⌋ = 1 k \times b-\lfloor (k\times b)/a \rfloor=1 k×b−⌊(k×b)/a⌋=1
所以,当 x = − ⌊ ( k × b ) / a ⌋ , y = k x=-\lfloor (k\times b)/a \rfloor,y=k x=−⌊(k×b)/a⌋,y=k 时, a × x + b × y = gcd(a,b) = 1 a \times x + b \times y = \text{gcd(a,b)}=1 a×x+b×y=gcd(a,b)=1。
s t 3 : a ≠ 0 , gcd ( a , b ) ≠ 0 st_3:a \neq 0,\text{gcd}(a,b)\neq0 st3:a=0,gcd(a,b)=0
设 g = gcd ( a , b ) g= \text{gcd}(a,b) g=gcd(a,b)。
设 x , y x,y x,y 为当 { a = a / g , b = b / g } \{ a=a/g,b=b/g \} {
a=a/g,b=b/g} 时的解,这里 gcd ( a / g , b / g ) = 1 \text{gcd}(a/g,b/g)=1 gcd(a/g,b/g)=1,所以可以使用 s t 2 st_2 st2。
因为, a g × x + b g × y = g \frac{a}{g}\times x+\frac{b}{g}\times y=g ga×x+gb×y=g。
所以, a × x + b × y = g = gcd(a,b) a \times x + b \times y =g= \text{gcd(a,b)} a×x+b×y=g=gcd(a,b)。
至此,证毕。
下面是我用我的结论写出来的代码,缺点是时间复杂度是 O ( n ) O(n) O(n) 的,这个日后在优化吧。
在代码中我只打开了 x , y x,y x,y 的打印,想看的详细一点的请自行解开封印 。
我的 a , b a,b a,b 是随机的,可以改为自己输入。
#include<bits/stdc++.h> #define ll long long using namespace std; inline ll Rand_1(ll x,ll y){
return (rand()*rand())%(y-x+1)+x; } inline Rand(ll x,ll y){
if(x>0)return Rand_1(x,y); if(y<0)return -Rand_1(-y,-x); ll op=Rand(1,2); if(op==1)return Rand_1(0,y); else return -Rand_1(1,-x); } inline pair<ll,ll>peishu(ll a,ll b){
if(a==0){
if(b<0)return{
0,-1}; if(b>0)return{
0,1}; } if(a<0){
pair<ll,ll>res=peishu(-a,b); res.first*=-1; return res; } if(b<0){
pair<ll,ll>res=peishu(a,-b); res.second*=-1; return res; } if(a==1)return{
-(b-1),1}; if(a==b)return{
1,0}; if(a>b){
pair<ll,ll>res=peishu(b,a); swap(res.first,res.second); return res; } if(b%a==0)return{
1,0}; if(__gcd(a,b)>1){
ll g=__gcd(a,b); pair<ll,ll>res=peishu(a/g,b/g); return res; } ll v=b-(b/a)*a; for(ll k=1;k<=a;k++)if(v*k%a==1)return{
-(b*k/a),k}; } signed main(){
srand(time(0)); ios::sync_with_stdio(false); for(ll q=1;q<=;q++){
// cout<<endl<<"q = "<<q<<endl; cout<<endl; ll k=Rand(1,100); ll a=k*Rand(-1000,1000),b=k*Rand(-1000,1000); // ll a,b;cin>>a>>b; cout<<"a = "<<a<<" b = "<<b<<endl; pair<ll,ll>res=peishu(a,b); ll x=res.first,y=res.second; cout<<"x = "<<x<<" y = "<<y<<endl; // cout<<"a*x = "<<a*x<<" b*y = "<<b*y<<" a*x+b*y = "<<a*x+b*y<<" gcd(a,b) = "<<abs(__gcd(a,b))<<endl; if(a*x+b*y!=abs(__gcd(a,b)))break; } return 0; }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/109697.html