• 数论入门_扩展欧几里得算法


    EXGCD

    学了扩展欧几里得算法好长时间了,打篇博客复习一下

    具体推导与用法如下


    拓展欧几里得算法

    主要解决求解同余方程的问题

    下面是一个关于x ,y的二元一次方程

    • ax + by = c

    根据裴蜀定理 ,如果gcd(a,b) | c,则此方程存在整数解(充分必要条件)

    因此我们仅当c=gcd(a,b)
    所以 ax1 + by1 = gcd(a,b)

    通过欧几里得算法,可得
    gcd(a,b)=gcd(b,a%b)

    这时 在 a=b,b=a%b的条件下
    bx2 + a%b y2 = gcd(b,a%b)

    所以 :

    • ax1 + by1 = bx2 + (a%b)y2

    假设k=a/b(向下取整),r=a%b

    那么 a = kb+r = b(a/b)+a%b,
    a%b = r = a-kb = a-b(a/b)

    bx2 + (a%b)y2

    = bx2 + (a-b(a/b))y2

    = bx2 - b(a/b)y2 + ay2

    =b(x2 - (a/b)y2) + ay2

    =ay2 + b(x2 - (a/b)y2)

    所以可得:

    bx2 + (a%b)y2 = ay2 + b(x2 - (a/b)y2)

    ax1 + by1 = bx2 + (a%b)y2 = ay2 + b(x2 - (a/b)y2)

    • ax1 + by1 = ay2 + b(x2 - (a/b)y2)

    惊喜地发现:

    • x1 = y2 , y1 = x2 - (a/b)y2

    得到此递归转移公式后,开始打exgcd部分的代码

    int exgcd(int a,int b,int &x1,int &y1) //附带求gcd的功能
    {
    	if(b==0){
    		x=1;  //当 ax+by=gcd(a,b)中b=0时,a=gcd(a,b),x=1,y=0
    		y=0;
    		return a; //gcd功能实现,b=0时gcd(a,b)=a
    	}
    	int x2,y2;
    	int t=exgcd(b,a%b,x2,y2);
    	x1=y2;
    	y1=x2-(a/b)*y2;
    	return t;  //返回gcd(a,b)
    }
    
    

    特解求出了通解便也好求了

    对于两个方程

    ax1 + by1 = c1
    , ax2 + by2 = c2

    x1=(c1/c2)x2 , y1=(c1/c2)y2

    所以此时回到在上面的方程

    • ax + by = c

    x = x1 ( c / gcd(a,b))

    y = y1 ( c / gcd(a,b))


    完整代码

    #include<iostream>
    using namespace std;
    int X,Y;
    int x1,y1; 
    int gcd(int a,int b)
    {
    	return b ?	gcd(b,a%b) : a;
    }
    int exgcd(int a,int b,int &x1,int &y1) //附带求gcd的功能
    {
    	if(b==0){
    		x=1;  //当 ax+by=gcd(a,b)中b=0时,a=gcd(a,b),x=1,y=0
    		y=0;
    		return a; //gcd功能实现,b=0时gcd(a,b)=a
    	}
    	int x2,y2;
    	int t=exgcd(b,a%b,x2,y2);
    	x1=y2;
    	y1=x2-(a/b)*y2;
    	return t;  //返回gcd(a,b)
    }
    
    int main()
    {
    	int a,b,c;
    	cin>>a>>b>>c;
    	int l=c/exgcd(a,b,x1,y1);
    	X=x1*l;
    	Y=y1*l;
    	cout<<X<<" "<<Y<<endl;
    }
    
    

    结束,蒟蒻鱼去补作业了

  • 相关阅读:
    oracle 日期函数
    SharpDevelop学习笔记(5)—— AddIns系统详解
    C#3.0 为我们带来什么(2) —— 自动属性
    SharpDevelop学习笔记(6)—— AddIn构建指南
    SharpDevelp2.0学习笔记(1)——SharpDevelp简单介绍
    对象数组根据某属性列的灵活排序
    SharpDevelop学习笔记(4)——SharpDevelop的核心
    也谈2007
    SharpDevelop学习笔记(2)——体系结构
    C#3.0 为我们带来什么(1) —— LINQ之Lambda
  • 原文地址:https://www.cnblogs.com/XJack/p/10850148.html
Copyright © 2020-2023  润新知