zoukankan      html  css  js  c++  java
  • 【逆元】HDU-1576

    逆元:

      同余方程 ax1(mod n),gcd(a,n) = 1 时有解,这时称求出的 x 为 a 的对模n的乘法逆元。(注意:如果gcd(a,n)如果不等于1则无解),解法还是利用扩展欧几里得算法求解方程 ax + ny = 1 求出 x。

     1     /**
     2      * 求逆元
     3      * ax = 1 (% mo),gcd(a,mo)=1
     4      * ax+mo*y=1
     5      * */
     6     public static long inverseElement(long a, long mo) throws Exception {
     7 
     8       long d = linearEquation(a, mo, 1);//ax+mo*y=1
     9       x = (x % mo + mo) % mo;//保证x>0
    10       return d;
    11     }

    题目:HDU-1576

      

      思路:设(A/B)%9973 = k, 则A/B = k + 9973x  (x未知), 因此A = kB + 9973xB,又A%9973 = n, 所以kB%9973 = n,  故kB = n + 9973y (y未知),故(k/n)B +(-y/n)*9973 = gcd(B,9973) = 1扩展欧几里得 求出k/n,  再乘以个n,记得取模,就是answer了。

      代码:

     1 import java.util.Scanner;
     2 
     3 /**
     4  * (A/B)%9973,求余,除法不满足交换性,可改为求B关于9973的逆元x,
     5  * 这样结果等价于Ax%9973等价于x*A%9973等价于xn%9973,
     6  */
     7 
     8 public class HDU1576 {
     9     
    10     public static void main(String[] args) {
    11         Scanner scanner = new Scanner(System.in);
    12         int T = scanner.nextInt();
    13         for (int i = 0; i < T; i++) {
    14             int n = scanner.nextInt();
    15             int b = scanner.nextInt();
    16             try {
    17                 MyGcd.inverseElement(b, 9973);
    18                 long x = MyGcd.x;
    19                 System.out.println(x*n%9973);
    20             } catch (Exception e) {
    21                 // TODO: handle exception
    22             }
    23         }
    24     }
    25 
    26     private static class MyGcd{
    27         static long x;
    28         static long y;
    29 
    30         public static long gcd(long m, long n) {
    31             return n == 0 ? m : gcd(n, m % n);
    32         }
    33 
    34         public static long ext_gcd(long a,long b){
    35             if (b==0) { 
    36                 x = 1;
    37                 y = 0;
    38                 return a;
    39             }
    40             long res = ext_gcd(b, a % b);
    41             long x1 = x;
    42             x = y;
    43             y = x1 - a / b * y;
    44             return res;
    45         }
    46 
    47         public static long linearEquation(long a, long b, long m) throws Exception {
    48             long d = ext_gcd(a, b);
    49             if (m % d != 0) {
    50                 throw new Exception("无解");
    51             }
    52             long n = m / d;
    53             x *= n;
    54             y *= n;
    55             return d;
    56         }
    57         
    58         public static long inverseElement(long a, long mo) throws Exception {
    59 
    60             long d = linearEquation(a, mo, 1);// ax+mo*y=1
    61             x = (x % mo + mo) % mo;// 保证x>0
    62             return d;
    63         }
    64     }
    65 }

      结果:

        

     

  • 相关阅读:
    机器人的运动范围
    矩阵中的路径
    MySql数据库表的基本连接
    Java虚拟机垃圾收集算法
    spring_boot 配置
    js 表格合并单元格
    js数组操作
    前端定位Position属性四个值
    form表单在发送到服务器时候编码方式
    多文件上传CommonsMultipartResolver
  • 原文地址:https://www.cnblogs.com/xiaoyh/p/10332966.html
Copyright © 2011-2022 走看看