zoukankan      html  css  js  c++  java
  • 51 Nod 1256 乘法逆元(数论:拓展欧几里得)

    1256 乘法逆元 

    基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

     收藏

     关注

    给出2个数M和N(M < N),且M与N互质,找出一个数K满足0 < K < N且K * M % N = 1,如果有多个满足条件的,输出最小的。

    Input

    输入2个数M, N中间用空格分隔(1 <= M < N <= 10^9)

    Output

    输出一个数K,满足0 < K < N且K * M % N = 1,如果有多个满足条件的,输出最小的。

    Input示例

    2 3

    Output示例

    2

    题解:
            对于求最小正K使K*M%N=1,可转换为求m*x+n*y=1的最小正解x;
            需要用到拓展欧几里和定理:
                    m*x1+n*y1=1;
                    n*x2+(m%n)*y2=1;(m%n=m-m/n*n;)
               =>m*x1+n*y1=m*y2+n*(x2-m/n*y2);
               =>x1=y2,y1=x2-m/n*y2;
               当n=0时可求出x=1;然后往前回溯即可求出结果
               补充:对于求解m*x+n*y=c的解时,若c%gcd(m,n)==0,方程的解将与方程 (m/gcd(m,n))*x + (n/gcd(m,n))*y =c/gcd(m,n) 的相  同。记新方程为a*x + b*y = d,其解将是方程 a*x + b*y = 1的d倍。

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    void gcd(int m,int n,int &x,int &y)
    {
            if(n==0){//此时m为初始时m,n的最大公约数1
                    x=1;//m*x+n*y=1;m=1,n=0,则x=1;
                    y=0;//任意取值
                    return ;
            }
            gcd(n,m%n,x,y);
            int tem=x;
            x=y;
            y=tem-(m/n)*y;
    }
    int main()
    {
            int m,n,x,y;
            while(~scanf("%d%d",&m,&n))
            {
                    gcd(m,n,x,y);//m*x+n*y=1(m,n互质则gcd(m,n)=1);
                    if(x>0)//x>0
                            printf("%d
    ",x);
                    else//若x<=0,则k要加上m的整数倍(只有这样才能通过改变y的值抵消使右边保持为1)
                            printf("%d
    ",n+x%n);
            }
            return 0;
    }
  • 相关阅读:
    Eleven-面向对象进阶
    Ten-面向对象
    Nine-常用模块
    Eight-内置函数和匿名函数
    Seven-递归函数和装饰器函数
    Six-迭代器和生成器
    Five-函数
    Four-深浅copy和文件操作
    Third-基础数据类型
    Second-基础
  • 原文地址:https://www.cnblogs.com/aeipyuan/p/9893099.html
Copyright © 2011-2022 走看看