數論雜記——裴蜀定理、拓展歐幾里得
阿新 • • 發佈:2020-07-29
裴蜀定理其實就是證明了一個二元一次方程
如果 x y 同時有解
那麼一定會有
模板題洛谷P4549
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 2e5+10; const int INF = 0x3f3f3f3f;View Codeconst int mod = 998244353; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} int n,i,a[maxn],ans; intmain() { n=read(); for (i=1;i<=n;i++) a[i]=read(); for (i=1;i<=n;i++) { if (a[i]<0) a[i]=-a[i]; ans=__gcd(ans,a[i]); } cout<<ans<<endl; return 0; }
而拓展歐幾里得則是在裴蜀定理的基礎上建立的
拓展歐幾里得的證明過程比較長,這裡貼出證明過程比較清晰的文章。https://www.zybuluo.com/samzhang/note/541890
實際上做的就是求解 的過程
void exgcd(ll a,ll b,ll &d,ll &x,ll &y){ //擴歐,ax+by=gcd(a,b),d存gcd if(!b)d=a,x=1,y=0; else exgcd(b,a%b,d,y,x),y-=x*(a/b); }View Code
模板洛谷P1082
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e3+7; const int INF = 0x3f3f3f3f; const int mod = 1e9+7; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} ll a,b,x,y; void exgcd(ll a,ll b,ll &x,ll &y) { if (!b) x=1,y=0; else exgcd(b,a%b,y,x),y-=x*(a/b); } int main() { a=read(),b=read(); exgcd(a,b,x,y); cout<<(x%b+b)%b<<endl; return 0; }View Code
稍微加深P1516
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e3+7; const int INF = 0x3f3f3f3f; const int mod = 1e9+7; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} ll x_1,y_1,m,n,l,d,x,y; void exgcd(ll a,ll b,ll &d,ll &x,ll &y) { if (!b) d=a,x=1,y=0; else exgcd(b,a%b,d,y,x),y-=x*(a/b); } int main() { x_1=read(),y_1=read(),m=read(),n=read(),l=read(); if (n-m<0) swap(x_1,y_1); exgcd(abs(n-m),l,d,x,y); if ((x_1-y_1)%d!=0) printf("Impossible"); else printf("%lld\n",((x*((x_1-y_1)/d))%(l/d)+(l/d))%(l/d)); return 0; }View Code
兩者結合
牛客2020多校訓練day3 F
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 505; const int INF = 0x3f3f3f3f; const int mod = 998244353; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} int a,b,g,t; ll c,d,e,f; void exgcd(ll a,ll b,ll &x,ll &y){ //擴歐,ax+by=gcd(a,b),d存gcd if(b==0)x=1,y=0; else exgcd(b,a%b,y,x),y-=x*(a/b); } int main() { t=read(); while (t--) { a=read(),b=read(); g=__gcd(a,b); if (g!=1) { printf("%d %d %d %d\n",a/g+1,b/g,1,b/g); continue; } d=0;f=0; for (int i=2;i*i<=b;i++) { if (b%i==0 && __gcd(i,b/i)==1) { d=1ll*i,f=1ll*(b/i); break; } } if (d==0 && f==0) printf("-1 -1 -1 -1\n"); else { exgcd(f,d,c,e); c*=1ll*a,e*=1ll*a; if(c>0&&e<0) printf("%lld %lld %lld %lld\n",c,d,-e,f); else printf("%lld %lld %lld %lld\n",e,f,-c,d); } } return 0; }View Code