exgcd

exgcd 解决的问题:

求出a*x+b*y=c(a,b,c为常量)的一组解,时间复杂度log(a)

首先先做一个证明

a*x+b*y=c 有整数解的充要条件是c整除gcd(a,b)

设gcd(a,b)=p

1.充分性:

a*x+b*y=c

a'*p*x+b'*p*y=c(a'=a/p)

p(a'*x+b'*y)=c;

因为x,y必须为整数

所以c必须整除p

2.必要性

使用欧几里得和数学归纳法可证明

首先b*x1+(a%b)*y1=c,有整数解,则a*x2+b*y2=c有整数解

a*x2+b*y2=b*x1+(a%b)*y1=b*x1+(a-floor(a/b)*b)*y1=a*y1+b*(x1-floor(a/b)*y1);floor表示向下取整

然后就可以得到对应关系x2=y1,y2=(1-floor(a/b))*y1;

显然最后的p,0有解

所以求这个a*x+b*y=c整数解的过程只需要不断递归运行到底层即可

最后一层p*x+0*y=c的解为x=c/p,y=0;之后再不断用关系x2=y1,y2=(x1-floor(a/b)*y1)推出上一层的解即可

例题:noip2012同余方程

https://www.luogu.org/problemnew/show/P1082

题目描述

求关于xx的同余方程 a x equiv 1 pmod {b}ax1(modb) 的最小正整数解。

输入输出格式

输入格式:

一行,包含两个正整数 a,ba,b,用一个空格隔开。

输出格式:

一个正整数 x_0x0,即最小正整数解。输入数据保证一定有解。

输入输出样例

输入样例#1: 复制
3 10
输出样例#1: 复制
7

说明

【数据范围】

对于 40%的数据,2 ≤b≤ 1,0002b1,000;

对于 60%的数据,2 ≤b≤ 50,000,0002b50,000,000;

对于 100%的数据,2 ≤a, b≤ 2,000,000,0002a,b2,000,000,000。

NOIP 2012 提高组 第二天 第一题

其实就是求ax+by=1的最小整数解

记得最后求出的x还要化为最小整数

#include<cstdio>
int x,y;
void exgcd(int a,int b){
    if(!b) x=1,y=0;
    else{
        exgcd(b,a%b);
        int tx=y,ty=x-a/b*y;
        x=tx,y=ty;
    }
}
int main(){
    int a,b;
    scanf("%d%d",&a,&b);
    exgcd(a,b);
    x%=b;x+=b,x%=b;
    printf("%d",x); 
    return 0;
} 
原文地址:https://www.cnblogs.com/bzmd/p/9776147.html