关于exgcd

关于exgcd

对于二元一次不定方程ax+by=c

首先由裴蜀定理得,ax+by=gcd(a,b),gcd(a,b)c

ax+by=gcd(a,b)

bx+(a%b)y=gcd(b,a%b)

gcd(a,b)=gcd(b,a%b)

ax+by=bx+(aabb)y

ax+by=ay+(xaby)b

void exgcd(int a,int b,int &x,int &y){
    if(b==0){
        x=1;y=0;
        return;
    }
    exgcd(b,a%b);
    int tmp=x;
    x=y;
    y=tmp-a/b*y;
}

对于方程ax+by=gcd(a,b)两边同时乘以cgcd(a,b),得到一组特解x0,y0

x0=cxgcd(a,b)

y0=cygcd(a,b)

考虑推通解:

ax0+by0=c

a(x0+kb)+b(y0ka)=c

dx 为满足要求的 kb 的最小整数,dy 为满足要求的 ka 的最小整数,因为 ka,kb 都是整数,当k=1gcd(a,b)

dx=bgcd(a,b)

dy=agcd(a,b)

方程通解可以表示为:

x=x0+kdx

y=y0kdy

x>0k>x0dx

y>0k>y0dy

x,y同时取到正整数,当且仅当

x0+1dxy01dy

x取得最小值时,y取得最大值

void work(){
    int a=read(),b=read(),c=read();
    int x=0,y=0;
    int g=exgcd(a,b,x,y);
    if(c%g!=0){//根据裴蜀定理,g不整除必无解
        printf("-1\n");
        return;
    }
    x=x*c/g;y=y*c/g;//求出特解
    int kx=b/g;
    int ky=a/g;
    int l=ceil(1.0*(-x+1)/kx);
    int r=floor(1.0*(y-1)/ky);
    if(l<=r){//两个都是正整数
        int num=r-l+1;//解的个数
        //当x取最小时,y对应取最大
        int minx=x+l*kx,maxy=y-l*ky;
        //当y取最小时,x对应取最大
        int miny=y-r*ky,maxx=x+r*kx;
        //printf("%lld %lld %lld\n",x,r,kx);
        printf("%lld %lld %lld %lld %lld\n",num,minx,miny,maxx,maxy);
    }
    else{
        int minx=x+l*kx;
        int miny=y-r*ky;
        printf("%lld %lld\n",minx,miny);
    }
}

posted @   blue_tsg  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示