• Java大数——快速矩阵幂


    Java大数——快速矩阵幂

    今天做了一道水题,尽管是水题,但是也没做出来。最后问了一下ChenJ大佬,才慢慢的改对,生无可恋了。。。。


    题目描述:

    给a,b,c三个数字,求a的b次幂对c取余。

    数据范围:多组样例循环输入,每一组输入a,b,c (1<=a,c<=10^9,1<=b<=10^1000000)。

    输入:

    2 2 2
    139123 123124121241452124412124 123121

    输出:

    0

    8984


    1、首先我们先定义大数变量

    BigInteger a,b,c;

     

    2、然后输入大数

    a=input.nextBigInteger();
    b=input.nextBigInteger();
    c=input.nextBigInteger();

     

    3、之后就是快速矩阵幂算法了

      快速矩阵幂就是用二进制来求幂的方法。在说快速矩阵幂之前,我们先看一个例子:A^23 = A^16 * A^4 * A^2 * A。16、4、2、1正好对应的就是23的二进制,即10111。

      当我们计算A^2的时候可以通过A*A来获得;当我们计算A^4的时候,可以通过A^2 * A^2获得;同理我们可以通过A^8 * A^8来得到A^16。这就是快速矩阵幂的思想,复杂度从O(n)降到了O(logn)。

      运算过程如下:

      (用temp记录当前幂的值)当位数==1时,temp*=A,且A=A*A,此时temp=A,A==A^2;

      继续  第二位也==1,继续temp*=A,且A=A*A;此时temp=A^3,A==A^4;

      继续  第三位也==1,继续temp*=A,且A=A*A;此时temp=A^7,A==A^8;

      第四位!=1,继续A=A*A;此时temp=A^7,A==A^16;

      继续  第五位==1,继续temp*=A,且A=A*A;此时temp=A^23,A==A^32;

      之后退出循环,返回结果temp。

      以上只用了5次循环,远远小于23次。

    完整代码

     1 import java.math.*;
     2 import java.util.*;
     3 public class Main {
     4 
     5     public static BigInteger POW (BigInteger a,BigInteger b,BigInteger c)
     6     {
     7         
     8         BigInteger ans = BigInteger.valueOf(1);//  大数 1
     9         BigInteger TW=BigInteger.ONE.add(BigInteger.ONE);// 大数 2
    10         while(!b.equals(BigInteger.ZERO))//如果b != 0  进入循环
    11         {
    12             if(b.remainder(TW).equals(BigInteger.ONE)) //  如果该位==1,则ans=ans*a;
    13                 ans = (ans.multiply(a)).remainder(c);//
    14             b=b.divide(TW);// 为了下一步计算b二进制的下一位
    15             a = (a.multiply(a)).remainder(c);// a*a 相当于A * A 或者 A^2 * A^2 等等
    16         }
    17         return ans;//返回
    18     }
    19 
    20     
    21     public static void main(String[] args) {
    22         // TODO Auto-generated method stub
    23         Scanner input = new Scanner(System.in);
    24         BigInteger a,b,c;
    25         while(input.hasNext()){
    26             a=input.nextBigInteger();
    27             b=input.nextBigInteger();
    28             c=input.nextBigInteger();
    29             System.out.println(POW(a,b,c));
    30         }
    31 
    32     }
    33 
    34 }

    总结

    不做不知道,一做吓一跳,水平太低了,要好好练习了。

    欢迎大家指正。

     

  • 相关阅读:
    Delphi泛型系列(很不错)[转静候良机]
    数组的排序
    数据存储到流几种形式(数据流 TStream)
    [转]Delphi TStream详解
    Delphi匿名方法[转 静候良机]
    神一样的崇拜这个女人...打破了我对我们苦b程序员极限的了解
    sql server cte语法
    GdiPlus[49]: 图像(一) 概览
    GdiPlus[51]: 图像(三) 关于呈现
    GdiPlus[47]: IGPMatrix 矩阵(二)
  • 原文地址:https://www.cnblogs.com/xia520/p/8640056.html
Copyright © 2020-2023  润新知