• AcWing 203. 同余方程 (线性同余方程)打卡


    求关于x的同余方程 ax ≡ 1(mod b) 的最小正整数解。

    输入格式
    输入只有一行,包含两个正整数a,b,用一个空格隔开。

    输出格式
    输出只有一行,包含一个正整数x,表示最小正整数解。

    输入数据保证一定有解。

    数据范围
    2≤a,b≤2∗109
    输入样例:
    3 10
    输出样例:
    7

    题意:要求满足题给的式子的最小正整数x

    思路:线性同余方程的经典问题

    ax ≡ m(mod b)  (原型)  

    ax ≡ 1(mod b)   ->    ax - by = 1(因为%b就相当于ax减掉若干个b)

    说明只有gcd(a,b)=1时才有解

    这里我们就可以化成扩展欧几里得来求解

    扩欧:   ax+by=gcd(a,b)  ,肯定有x,y能满足这个条件

    证明:

    1.gcd(a,b)=gcd(b,a%b)

    2. 欧几里得算法算到最后,当b=0时,a*1+0*0=gcd(a,0)

    3. bx+a%by = gcd(b,a%b)   ->    bx +  (a-a/b*b)y  = gcd(b,a%b)   ->   ay +  b(x-a/b*by) = gcd(b,a%b)  ->  ax' + by' = gcd(a,b)

    所以由2我们可知最简形式有x,y满足定理,由1可以推出3,由3可知可以由任何一步推出另一步,所以我们可以用最简形式推出所有的

    所以证明扩欧定理的正确性

    线性同余方程可以化简出扩欧的式子,然后求出x

    然后通解为  x+num*b

    这里要求为正整数,所以我们要+b%b

    #include<bits/stdc++.h>
    #define maxn 100005
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    ll x,y;
    ll exgcd(ll a,ll b){
        if(b==0){
            x=1;
            y=0;
            return a;
        }
        ll z=exgcd(b,a%b);
        ll t=x;
        x=y;
        y=t-a/b*y;
        return z;
    }
    int main(){
        ll a,b;
        cin>>a>>b;
        ll z=exgcd(a,b);
        //cout<<z<<endl;
        cout<<(x%b+b)%b<<endl; 
    }
  • 相关阅读:
    noip2018练习总结
    东方CannonBall (概率DP)
    数论
    逆序对
    USACO5.3 校园网Network of Schools(Tarjan缩点)
    USACO09FEB 改造路Revamping Trails(分层图模板)
    Comet OJ模拟赛 Day1
    Tarjan模板
    NOIP 天天爱跑步(树上差分)
    树上差分
  • 原文地址:https://www.cnblogs.com/Lis-/p/11087806.html
Copyright © 2020-2023  润新知