zoukankan      html  css  js  c++  java
  • 扩展欧几里得算法

    扩展欧几里得算法

    引入

    日常生活中我们会遇到一些不定方程,注意本文中所考虑的解都是整数解,如:

    \[3x+y=5 \]

    我们可以知道这个方程有解,如:

    \[\begin{cases}x=1\\y=2\end{cases},\begin{cases}x=2\\y=-1\end{cases},\begin{cases}x=3\\y=-4\end{cases}......\begin{cases}x=1+k\\y=2-3k\end{cases} \]

    我们可以知道这个方程有无数的整数解。

    算法

    我们的扩欧就是来解决形如:

    \[ax+by=\gcd(a,b) \]

    这一类 \(x,y\) 整数解的求解问题的。

    我们可以知道 \(\gcd(a,b)=\gcd(b,a\%b)\)。所以我们在设一个方程:

    \[bx'+(a\%b)y'=\gcd(b,a\%b) \]

    所以我们有:

    \[ax+by=bx'+(a\%b)y' \]

    \[ax+by=bx'+(a-\lfloor\frac{a}{b}\rfloor\cdot b)y' \]

    \[ax+by=ay'+b\cdot(x'-\lfloor\frac{a}{b}\rfloor\cdot y') \]

    所以 \(x=y',y=x'-\lfloor\frac{a}{b}\rfloor\cdot y'\)

    递归求解即可:

    #pragma GCC optimize("Ofast","-funroll-loops","-fdelete-null-pointer-checks")
    #pragma GCC target("ssse3","sse3","sse2","sse","avx2","avx")
    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    
    int read() {
    	char ch=getchar();
    	int f=1,x=0;
    	while(ch<'0'||ch>'9') {
    		if(ch=='-')
    			f=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9') {
    		x=x*10+ch-'0';
    		ch=getchar();
    	}
    	return f*x;
    }
    
    int a,b,x,y;
    
    void exgcd(int a,int b,int &x,int &y) {
        if(b==0) {
            x=1,y=0;
            return ;
        }
        exgcd(b,a%b,x,y);
        int xx=y;
        int yy=x-a/b*y;
        x=xx;
        y=yy;
    }
    
    signed main() {
        a=read();b=read();
    
        exgcd(a,b,x,y);
    
        cout<<x<<" "<<y<<endl;
    
    	return 0;
    }
    
    
  • 相关阅读:
    HSSFSheet XSSFWorkbook SXSSF Java读取Excel数据
    js 获取相同name元素的属性值
    jsp 页面返回、本页面刷新
    Spring MVC启动过程(1):ContextLoaderListener初始化
    eclipse中无法查看引用的jar包源码
    eclipse添加tomcat服务器
    PLsql链接oracle配置
    JDK 与TOMCAT的安装详解
    JSON笔记
    linux系统命令大全
  • 原文地址:https://www.cnblogs.com/huayucaiji/p/exgcd.html
Copyright © 2011-2022 走看看