二分求幂,快速求解a的b次幂
一个引子
如何求得a的b次幂呢,那还不简单,一个for循环就可以实现!
void main(void)
{
int a, b;
int ans = ;
cin >> a >> b;
for (int i = ; i <= b; i++)
{
ans *= a;
}
cout << ans;
}
那么如何快速的求得a的b次幂呢?上面的代码还可以优化吗?
当然是ok的!下面就介绍一种方法-二分求幂。
二分求幂
所谓二分求幂,即是将b次幂用二进制表示,当二进制位k位为1时,需要累乘a的2^k次方。
下面优化一下上面的代码:
void main(void)
{
int a, b;
int ans = ;
cin >> a >> b;
while (b != )
{
//当二进制位k位为1时,需要累乘a的2^k次方,然后用ans保存
if (b % == )
{
ans *= a;
}
a *= a;
//每次除以2,转换成二进制位
b /= ;
}
cout << ans;
}
举个例子,当b = 5时,b的二进制为101。
| 循环次数 | 二进制位 | ans值 | a值 | b值 |
| 0 | 101 | 1 | a | 5 |
| 1 | 10 | 2 | a2 | 2 |
| 2 | 11 | 2 | a4 | 1 |
| 3 | 01 | 32 | a16 | 0 |
从上表我们可以直观的看出5次幂就可以转换为(2^0+2^2),即a的5次幂就转变为a的(2^0+2^2)次幂,即a的2^0与a的2^2的乘积。
再来个例子-巩固
此题来源于九度教程“人见人爱A^B”。
题目描述:
求A^B的最后三位数表示的整数。
输入:
输入数据包含多个测试实例,每个实例占一行,由两个正整数a和b组成,其中(1<=a,b<=10000),如果a = 0,被= 0,则表示输入数据结束,不做处理。
输出:
对于每个测试实例,输出a^b的最后三位表示的整数,每个输出占一行。
样例输入:
2 3
12 6
6789 10000
0 0
样例输出:
8
984
1
对于这道题,完全可以用上面的二分求解方法,可以仿照上面的代码进行实现。但是有一点需要注意的是,我们不肯能定义一个整型变量或者long long类型的变量取保存如样例给出的数据a = 6789,b=10000,a^b的计算结果。因为数字太庞大了,在整数范围内是无法表示的。所以我们可以只保存每次计算结果的后三位,因为最终结果的后三位取决于其中间值的后三位。
好吧,给出代码:
void main(void)
{
int a, b;
while ((cin >> a >> b))
{
int ans = ;
if (a == && b == )
break;
while (b != )
{
//当二进制位k位为1时,就累加a的2^k次方
if (b % == )
{
ans *= a;
ans %= ;
}
a *= a;
a %= ;
//每次除以2,转换成二进制位
b /= ;
}
cout << ans;
} }
二分求幂,快速求解a的b次幂的更多相关文章
- HDU 2035 人见人爱A^B(二分求幂,快速求幂)
题意:求A的B次方的后三位数字 思路1:常规求幂,直接取余求解 代码: #include<iostream> #include<cstdio> using namespace ...
- 九度OJ 1085 求root(N, k) -- 二分求幂及快速幂取模
题目地址:http://ac.jobdu.com/problem.php?pid=1085 题目描述: N<k时,root(N,k) = N,否则,root(N,k) = root(N',k). ...
- 二分求幂/快速幂取模运算——root(N,k)
二分求幂 int getMi(int a,int b) { ; ) { //当二进制位k位为1时,需要累乘a的2^k次方,然后用ans保存 == ) { ans *= a; } a *= a; b / ...
- SPOJ AMR10E Stocks Prediction --二分求和+矩阵快速幂
题意:给一个递推式S(n) = a1*S(n-1)+...+aR*S(n-R),要求S(k)+S(2k)+...+S(nk)的值. 分析:看到n的大小和递推式,容易想到矩阵快速幂.但是如何转化呢? 首 ...
- 如何快速求解第一类斯特林数--nlog^2n + nlogn
目录 参考资料 前言 暴力 nlog^2n的做法 nlogn的做法 代码 参考资料 百度百科 斯特林数 学习笔记-by zhouzhendong 前言 首先是因为这道题,才去研究了这个玩意:[2019 ...
- 牛客网 牛客小白月赛12 B.华华教月月做数学-A^B mod P-快速幂+快速乘
链接:https://ac.nowcoder.com/acm/contest/392/B来源:牛客网 华华教月月做数学 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其 ...
- HDU 4549 矩阵快速幂+快速幂+欧拉函数
M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Sub ...
- 取模性质,快速幂,快速乘,gcd和最小公倍数
一.取模运算 取模(取余)运算法则: 1. (a+b)%p=(a%p+b%p)%p; 2.(a-b)%p=(a%p-b%p)%p; 3.(a*b)%p=(a%p * b%p)%p; 4.(a^b)%p ...
- hdu5256 二分求LIS+思维
解题的思路很巧,为了让每个数之间都留出对应的上升空间,使a[i]=a[i]-i,然后再求LIS 另外二分求LIS是比较快的 #include<bits/stdc++.h> #define ...
随机推荐
- 使用 bat cmd命令杀掉 删掉运行的程序
删掉所有xx.exe开启的进程 taskkill /f /im xx.exe 开启xx.exe start xx.exe 根据标题栏信息删除 taskkill /f /FI "windows ...
- mysql 5.6.23的源码安装
http://634871.blog.51cto.com/624871/1325914 首先删除系统自带的mysql rpm -qa | grep mysql rpm -e mysql //普 ...
- oracle递归层级查询 start with connect by prior
递归层级查询:start with connect by prior 以部门表作为解析 表结构:dept{id:'主键',name:'部门名称',parent_id:'父亲id'} select * ...
- 微服务之springcloud技术栈
一.微服务架构图: 二.技术介绍:(技术选型随着代码的编写会完成) 关于技术选型,我盗了一张微服务技术栈的图,如下:原文:http://www.jianshu.com/p/2da6becfb019 我 ...
- javascript中字符串与数组互转的方法分享
说明:1.join()方法:用于把数组中的所有元素放入一个字符串,元素是通过指定的分隔符进行分隔的.指定分隔符方法join("$");其中$可以是任意字符2.split()方法:用 ...
- java jvm perf
http://www.oracle.com/technetwork/java/performance-138178.html http://www.oracle.com/technetwork/jav ...
- 黑客编程教程(二)Win API编程简介
第二节 Win API编程简介 下面介绍一下WIN API. 我们需要自己编写一个工具时,必然会用到很多操作windows和控制windows的函数,这些函数就是windows API. API是Ap ...
- python 开发在线音乐播放器-简易版
在线音乐播放器,使用python的Tkinter库做了一个界面,感觉这个库使用起来还是挺方便的,音乐的数据来自网易云音乐的一个接口,通过urllib.urlopen模块打开网址,使用Json模块进行数 ...
- cocos2d-x解决中文乱码问题的几种办法
昨天改写cocos2d-x的例程,想在其基础上加上一个计分系统.没有分数实在让人没有玩下去的动力! 我在主场景上加上了一个CCLabelTTF,用于显示分数. 但是意外的发现,当内容含有中文时,CCL ...
- ny17 单调递增最长子序列
单调递增最长子序列时间限制:3000 ms | 内存限制:65535 KB难度:4 描述 求一个字符串的最长递增子序列的长度 如:dabdbf最长递增子序列就是abdf,长度为4 输入 ...