快速幂详解(超详细!!!)

快速幂的作用

当我们做一些高次幂的计算时,就不能直接进行暴力的计算。例如:需要计算 2 n 2^n 2n并且 n ≤ 1 0 18 n\le 10^{18} n1018。这时候如果我们直接进行暴力的计算,时间复杂度为 O ( n ) O(n) O(n),那么肯定会超时,这时候我们就需要一些更优美的算法来帮我们解决这个问题。

快速幂的实现

思路

首先我们要明确一点,对于一个 m n m^n mn,当 n n n为偶数时, m n = ( m 2 ) n 2 m^n=(m^2)^\frac n2 mn=(m2)2n
如果知道了这一点我们的问题就迎刃而解了。


求解 2 k 2^k 2k
定义: n o w now now为当前的底数, f f f为临时存放处。
k k k为偶数时, n o w × = n o w , k / = 2 now\times=now,k/ =2 now×=now,k/=2
k k k为奇数时, k − − , f ∗ = n o w k--,f*=now k,f=now,然后再以 k k k为偶数的情况进行计算。
相信大家看了这简单的算法应该都能理解吧。

Code

int quickpow(int n,int k) {
	long long now=n,f=1;
	while(k>1) {
		if(k%2==1) k--,f*=now;
		if(k) now*=now,k/=2;
	}
	return now*f;
}

例题

在这里插入图片描述
Input
在这里插入图片描述
Output
在这里插入图片描述
在这里插入图片描述


这一题我们可以明显的看出规律,答案其实就是 2 n − 1 2^{n-1} 2n1
快速幂求解即可,时间复杂度 O ( l o g ( n ) ) O(log(n)) O(log(n))

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#define p 1000000007
using namespace std;
long long ans=2,n;
void qpow(long long k) {
	long long f=1;
	while(k>1) {
		if(k%2!=0) f=(ans*f)%p,k--;
		if(k) ans=(ans*ans)%p,k/=2;
	}
	ans=(ans*f)%p;
}
int main() {
	scanf("%lld",&n);
	qpow(n-1);
	printf("%lld",ans);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值