扩展欧几里得 求解不定方程和逆元

好气啊,本来写完了一篇关于gcd,exgcd相关证明的声情并茂的文章;

结果,手残……关了……没保存……QAQ,所以不想再详细写一篇了,百度有很多;

exgcd

1.求解同余方程,不定方程,逆元;
2.中国剩余定理……;

证明:
https://www.baidu.com/自行百度;

小学数学相关内容:
a是b的倍数(b是a的约数),a可以被b整除(b可以整除a);

不定方程:

ax+by=c;
前提:

c mod gcd(a,b)=0;

证明:
很简单,
若ax+by=c有解;
因为
a mod gcd(a,b)=0,
b mod gcd(a,b)=0;
所以
ax+by一定被gcd(a,b)整除;
所以
c一定被gcd(a,b)整除;

求得ax+by=gcd(a,b)的解x0,y0;

显然,ax+by=c的解:

x1=x0*c/gcd(a,b);
y1=y0*c/gcd(a,b);

但是只能求解一组解,怎么求解多组解呢?

x2=x1+b/gcd(a,b)*t;
y2=y1-a/gcd(a,b)*t;

原因:
除gcd是为了防止漏解,因为a,b不一定互质;

t为任意实数;

#include<iostream>
using namespace std;
int x,y;
int exgcd(int a,int b,int &x,int &y)
{
    int r,k;
    if(!b) {x=1,y=0;return a;}
    r=exgcd(b,a%b,x,y);
    k=x,x=y,y=k-a/b*y;
    return r;
}
int hh(int a,int b,int c)
{
    int d=exgcd(a,b,x,y);
    if(c%d) return 0;
    int k=c/d;
    x*=k; y*=k;
    return d;
}
void solve()
{
    int a,b,c,k,cnt=1;
    cin>>a>>b>>c;
    if(k=hh(a,b,c))//若有解;
    {
        cout<<cnt<<" : "<<x<<" "<<y<<endl;
        while(cnt++)
        {
            x+=b/k*cnt,y=y-a/k*cnt;
            cout<<cnt<<" : "<<x<<" "<<y<<endl;
            if(cnt==10) cnt=0;
        }
    }
}
int main()
{
    solve();
    return 0;
}

逆元:

ax=1(mod b)

=> ax+by=1;

x是a关于b的逆元;
exgcd求解~;

K.O

总结:

noip的数论并不是很难,关键是多动手写写,不要光想;

NOIP 2017 RP ++!

神犇链接:http://blog.csdn.net/clove_unique/article/details/53135707

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值