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次。
完整代码
import java.math.*;
import java.util.*;
public class Main { public static BigInteger POW (BigInteger a,BigInteger b,BigInteger c)
{ BigInteger ans = BigInteger.valueOf(1);// 大数 1
BigInteger TW=BigInteger.ONE.add(BigInteger.ONE);// 大数 2
while(!b.equals(BigInteger.ZERO))//如果b != 0 进入循环
{
if(b.remainder(TW).equals(BigInteger.ONE)) // 如果该位==1,则ans=ans*a;
ans = (ans.multiply(a)).remainder(c);//
b=b.divide(TW);// 为了下一步计算b二进制的下一位
a = (a.multiply(a)).remainder(c);// a*a 相当于A * A 或者 A^2 * A^2 等等
}
return ans;//返回
} public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
BigInteger a,b,c;
while(input.hasNext()){
a=input.nextBigInteger();
b=input.nextBigInteger();
c=input.nextBigInteger();
System.out.println(POW(a,b,c));
} } }
总结
不做不知道,一做吓一跳,水平太低了,要好好练习了。
欢迎大家指正。
Java大数——快速矩阵幂的更多相关文章
- CodeForces621E 快速矩阵幂优化dp
有时些候在用快速矩阵幂优化dp的时候,它的矩阵乘法是不那么容易被具体为题目背景的意思的,大多数时候难以理解矩阵之间相乘的实际意义,正如有时候我们不知道现在在做手头这些事情的意义,但倘若是因一个目标而去 ...
- HDU - 6395 Sequence (分块+快速矩阵幂)
给定递推式: 求Fn. 分析:给出的公式可以用快速矩阵幂运算得到,但 P/n 整除对于不同的i,值是不同的. 可以根据P将3-n分成若干块,每块中P整除n的值是相同的.分块的时候要注意判断. 将每块的 ...
- HDU----(4291)A Short problem(快速矩阵幂)
A Short problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- HDU----(4549)M斐波那契数列(小费马引理+快速矩阵幂)
M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Sub ...
- HDU----(2157)How many ways??(快速矩阵幂)
How many ways?? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- Matrix Power Series(POJ 3233 构造新矩阵求解+ 快速矩阵幂)
题目大意:给定A,k,m(取模),求解S = A + A2 + A3 + … + Ak. 思路:此题为求解幂的和,一开始直接一个个乘,TLE.时间消耗在累加上.此处巧妙构造新矩阵 p= A 0 ...
- Tr A(HDU 1575 快速矩阵幂模板)
Tr A Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- POJ 3070 - 快速矩阵幂求斐波纳契数列
这题并不复杂. 设$A=\begin{pmatrix} 1 & 1 \\ 1 & 0 \end{pmatrix}$ 由题中公式: $\begin{pmatrix}f(n+1) & ...
- 多校第五场 归并排序+暴力矩阵乘+模拟+java大数&记忆化递归
HDU 4911 Inversion 考点:归并排序 思路:这题呀比赛的时候忘了知道能够用归并排序算出逆序数,可是忘了归并排序的实质了.然后不会做-- 由于看到题上说是相邻的两个数才干交换的时候.感觉 ...
随机推荐
- 如何在mac上运行vue项目
使用终端安装Vue运行环境 1.安装 Homebrew Homebrew 是osx下面最优秀的包管理工具,没有之一.先在终端查看是否已安装brew brew -v 如果返回 Homebrew 的版本号 ...
- 大数据入门第八天——MapReduce详解(四)本地模式运行与join实例
一.本地模式调试MR程序 1.准备 参考之前随笔的windows开发说明处:http://www.cnblogs.com/jiangbei/p/8366238.html 2.流程 最重要的是设置Loc ...
- JSON解析工具——Jackson的简单使用
什么是Jackson 可以轻松实现Java对象与JSON字符串的转换 准备工作:导包 Jackson的jar all下载地址:http://jackson.codehaus.org/1.7.6/jac ...
- JQuery第一天——入门概述与选择器
一.什么是JQuery 一个流行的js库 核心理念:write less , do more 优势: 轻量级 强大的选择器 出色的 DOM 操作的封装 可靠的事件处理机制 完善的 Ajax 出色的浏 ...
- mysql 5.7.12 winx64安装配置方法图文教程
这篇文章主要为大家分享了mysql 5.7.12winx64安装配置方法图文教程,感兴趣的朋友可以参考一下 之前安装mysql时未做总结,换新电脑,补上安装记录,安装的时候,找了些网友的安装记录, ...
- EntityFramework使用动态Lambda表达式筛选数据
public static class PredicateBuilder { public static Expression<Func<T, bool>> True<T ...
- 柯朗微积分与数学分析习题选解(1.1 节 e)
一直在读<陶哲轩实分析>,陶的书非常的严谨,环环相扣,但是也有个缺点就是计算性的例子和应用方面的例子太少了.所以就又找了本柯朗的<微积分与数学分析>搭配着看.柯朗的书的习题与陶 ...
- POJ-2299 Ultra-QuickSort (树状数组)
题目链接:Ultra-QuickSort 题意: 给出了一个序列,序列中有n个数,现在每次操作能交换相邻的两个数,要求操作几次可以将这个序列转换为一个从小到大排序的序列. 题解: 我的解法是先把所有的 ...
- Unity学习笔记(3):一些常用API和应用场景
Mathf.Lerp(float a,float b,float t)插值函数,当a < b时往a中插入t,以此来实现颜色,声音等渐变效果. GameObject.FindWithTag(str ...
- 1.21 贪心入门上午PAT例题题解
1.B1023 #include<cstdio> int a[10]; int main() { for(int i=0;i<=9;i++) { scanf("%d&quo ...