zoukankan      html  css  js  c++  java
  • 数论杂记——裴蜀定理、拓展欧几里得

    裴蜀定理其实就是证明了一个二元一次方程

    如果 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; 
    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 n,i,a[maxn],ans;
    int main()
    {
        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;
    }
    View Code

    而拓展欧几里得则是在裴蜀定理的基础上建立的

    拓展欧几里得的证明过程比较长,这里贴出证明过程比较清晰的文章。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
    ",((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
    ",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
    ");
            else
            {
                exgcd(f,d,c,e);
                c*=1ll*a,e*=1ll*a;
                if(c>0&&e<0) printf("%lld %lld %lld %lld
    ",c,d,-e,f);
                    else printf("%lld %lld %lld %lld
    ",e,f,-c,d);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    jstl标签
    get和post
    try中的局部变量在finally中是找不到的。
    bzoj 4408: [Fjoi 2016]神秘数 数学 可持久化线段树 主席树
    ZOJ2112 BZOJ1901 Dynamic Rankings 树套树 带修改的区间第k小
    BZOJ 2120: 数颜色 带修改的莫队算法 树状数组套主席树
    POJ2104 K-th Number 不带修改的主席树 线段树
    POJ 2891 Strange Way to Express Integers 中国剩余定理 数论 exgcd
    POJ1151 Atlantis 水题 计算几何
    BZOJ 2333: [SCOI2011]棘手的操作 可并堆 左偏树 set
  • 原文地址:https://www.cnblogs.com/Y-Knightqin/p/13394256.html
Copyright © 2011-2022 走看看