[Luogu P1082]同余方程

题目链接

这道题求关于x的同余方程ax≡1(mod b)的最小正整数解。换而言之方程可以转换为ax+by=1,此时有y为负数。此时当且仅当gcd(a,b)|1时,方程有整数解。

于是乎这道题就变成了ax+by=gcd(a,b)即扩展欧几里得问题。如何解决这个问题呢?

由gcd的基本性质可以得出:gcd(b,a%b)=gcd(a,b),这个值我们设为g。既有ax+by=g,bx1+(a%b)y1=g,变形得,bx1+(a-a/b*b)y1=g,展开得ay1+b(x1-y1*a/b)=g,此时显而易见有一组解为:x=y1,y=x1-y1*a/b

那么所有的解都可以由于后面的解得出,于是用递归实现。

//#include<fstream>
//#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
//#include<queue>
//#include<vector>
//#include<stack>
//#include<map>
using namespace std;
long long read(){
    long long res=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        res=res*10+(ch-'0');
        ch=getchar();
    }
    return res*f;
}
//ax+by=gcd(a,b);
long long x,y,xt;
long long a,b;
void exgcd(int a,long long b){
    if(b==0){
        x=1;y=0;
        return;
    }
    exgcd(b,a%b);
    xt=x;
    x=y;
    y=xt-a/b*y; 
}
int main(){
a=read();b=read();
exgcd(a,b);
while(x<0)x+=b;
x%=b;
cout<<x;
return 0;
}

 

posted @ 2019-04-13 11:39  clockwhite  阅读(143)  评论(0编辑  收藏  举报