IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> C++数据结构与算法分析——快速幂 -> 正文阅读

[数据结构与算法]C++数据结构与算法分析——快速幂

幂运算

幂运算是一种幂的运算,它有一个性质:同底数幂相乘,底数不变,指数相加

求幂运算的朴素做法 O ( k ) O(k) O(k)

假设此时我们需要求底为a,指数为k的幂的值,即求 r e s = a k res = a^k res=ak,那么我们很容易想到最直接的做法:令 r e s = 1 res = 1 res=1,让res乘以ka即可得到答案。

代码:

int power(int a,int k){
	int res = 1;
	while(k --) res *= a;
	return res;
}

容易看出,它总共进行了k次运算,因此时间复杂度为 O ( k ) O(k) O(k)

快速幂 O ( l o g k ) O(logk) O(logk)

有时候当要求的次方大于一定值时,用朴素做法求幂就会显得效率很低,那么有没有什么方法可以快速求幂呢?
这就需要用到上方的性质:同底数幂相乘,底数不变,指数相加
假设我们需要求 3 7 3^7 37,那么我们可以分为 3 ? 3 ? 3 ? 3 ? 3 ? 3 ? 3 3 * 3 * 3 * 3 * 3 * 3 * 3 3?3?3?3?3?3?3,也可以等于 3 2 ? 3 2 ? 3 2 ? 3 3^2 * 3^2 * 3^2 * 3 32?32?32?3,原因是它们的指数之和为 7 7 7,那么我们就会想到二进制优化
7 = 4 + 2 + 1 = 2 2 + 2 1 + 2 0 = 11 1 2 7 = 4 + 2 + 1 = 2^2 + 2^1 + 2^0 = 111_2 7=4+2+1=22+21+20=1112?
于是 3 7 = 3 11 1 2 3^7 = 3^{111_2} 37=31112?
因此我们只需要处理出指数k的二进制表示及每个二进制数下的乘数即可。

  1. 如果k0,停止运算
  2. 每当 k k k的最低位数为0时, r e s res res不进行运算,为1时, r e s = r e s ? a res = res * a res=res?a
  3. 然后将 a = a ? a a = a * a a=a?a(每个二进制数下的乘数)
  4. 最后 k > > = 1 ( k = k / 2 ) k >>= 1(k = k / 2) k>>=1(k=k/2)

3 7 ( 3 11 1 2 ) 3^7(3^{111_2}) 37(31112?)
r e s = 1 res = 1 res=1

k ! = 0 k != 0 k!=0
k的最低位为1, r e s = r e s ? a = 1 ? 3 = 3 res = res * a = 1 * 3 = 3 res=res?a=1?3=3
a = a ? a = 9 a = a * a = 9 a=a?a=9
k > > = 1 k >>= 1 k>>=1 k = k / 2 = 3 ( 11 1 2 > > 1 = = 1 1 2 ) k = k / 2 = 3(111_2 >> 1 == 11_2) k=k/2=3(1112?>>1==112?)

k ! = 0 k != 0 k!=0
k的最低位为1, r e s = r e s ? a = 3 ? 9 = 27 res = res * a = 3 * 9 = 27 res=res?a=3?9=27
a = a ? a = 81 a = a * a = 81 a=a?a=81
k > > = 1 k >>= 1 k>>=1 ( k = k / 2 = 1 , ( 1 1 2 > > 1 = = 1 2 ) ) (k = k / 2 = 1,(11_2 >> 1 == 1_2)) (k=k/2=1,(112?>>1==12?))

k ! = 0 k != 0 k!=0
k的最低位为1, r e s = r e s ? a = 27 ? 81 = 2187 res = res * a = 27 * 81 = 2187 res=res?a=27?81=2187
a = a ? a = 6561 a = a * a = 6561 a=a?a=6561
k > > = 1 k >>= 1 k>>=1 ( k = k / 2 = 0 , ( 1 2 > > 1 = = 0 2 ) ) (k = k / 2 = 0,(1_2 >> 1 == 0_2)) (k=k/2=0,(12?>>1==02?))

k = = 0 k == 0 k==0
返回 r e s = 2187 res = 2187 res=2187

代码

int qmi(int a,int k){ // 求a的k次方
	int res = 1;
	while(k){
		if(k & 1) res = res * a;
		a = a * a;
		k >>= 1;
	}
	return res;
}

含求模运算的代码

int qmi(int a,int k,int p){ // 求a的k次方模p
	int res = 1;
	while(k){
		if(k & 1) res = (long long)res * a % p;
		a = (long long)a * a % p;
		k >>= 1;
	}
	return res;
}

可以看出它只需要进行 l o g k logk logk次运算,因此时间复杂度为 l o g k logk logk

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-26 12:25:59  更:2021-10-26 12:26:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:18:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码