ACM_快速幂
来源:互联网 发布:程序员述职报告范文 编辑:程序博客网 时间:2024/06/05 04:52
快速计算一个数的多少次幂(底数一半是整数, 如果是浮点数, 建议直接用库函数的pow, 指数必须是整数)
ll exp_mod(ll a, ll b){ ll ret = 1; while(b){ if(b & 1) ret = ret * a; a = a * a; b >>= 1; } return ret;}
程序解释:
比如3 ^ 5 = 243
快速幂是指数基于二进制的计算 所以把他写成这样 3 ^ 101 (101是二进制)
那么快速幂的计算过程是这样的:
1. 结果用ret记录(初始为1)
2.我们发现指数的二进制下的最后1位是1说明这一位有这个数, 然后ret = ret * a , ret = 3;
3.然后我们把指数右移一位, 指数(也就是程序中的b) = 10(二进制) 同时对应的k 也应该”右移一位”指向101中的0 如何操作呢? 只需要a = a * a, a = 9;
返回步骤2
再次循环, 直到指数为0(因为指数一直右移, 所以肯定能为0);
所以3 ^ 5 的实际过程
初始化 k = 3, b = 101, a = 3, ret = 1;
第一次循环{
发现b的最低位是1 ret = ret * a , ret = 3;
a = a * a, a = 9;
b = b >> 1, b = 10(二进制)
}
第二次循环{
发现b的最低位是0 ret不变
a = a * a, a = 81;
b = b >> 1, b = 1;
}
第三次循环{
发现b的最低位是1, ret = ret * a, ret = 243;
a = a * a, a = 243;
b = b >> 1, b = 0;
发现b等于0 所以在这次循环结束后退出
}
返回ret也就是243, 于是得到3 ^ 5 = 243;
整个算法的效率是log N, 应该比库函数的pow快吧, 而且最主要的没有精度损失!!!
可以加上mod(需要取余的数)
ll exp_mod(ll a, ll b, ll mod){ ll ret = 1; a %= mod; while(b){ if(b & 1) ret = (ret * a) % mod; a = a * a % mod; b >>= 1; } return ret;}
- ACM_快速幂
- ACM_快速排序算法
- acm_起点
- acm_蜂巢
- acm_求最值
- ACM_ Classy
- ACM_阶段性总结 ACM_动态规划(DP)
- ACM_调试技巧
- ACM_暑期计划
- ACM_归并排序算法
- ACM_并查集
- ACM_邻接表
- ACM_素数筛选
- ACM_并查集
- ACM_线段树
- ACM_扩展欧几里德算法
- ACM_状压DP
- ACM_普通DP
- 9.3小假期
- "抱歉,无法发起临时会话,您可以 添加对方为好友以发送消息"解决办法
- 【读书有感】如何高效学习
- mysql外连接查询用法
- PAT Advanced 1035
- ACM_快速幂
- stm32之keil开发环境搭建
- csdn设置自己的博客栏目
- 自学QT之颜色选择对话框
- Cocos2d-x tinyxml2用于xml的解析,自动生成xml文件和解析xml文件
- 运行时异常与一般异常有何异同
- 学数学的伤不起
- 在Struts2中jsp前台传值到后台的三种方法
- AlertDialog提示框的使用