前言
顾名思义,快速幂就是快速算底数的n次幂。其时间复杂度为 O(log₂N), 与朴素的O(N)相比效率有了极大的提高。
一、基本思路
(1)当b是奇数时,那么有 a^b = a * a^*(b-1)
(2)当b是偶数时,那么有 a^b = a^(b/2) * a^(b/2)
例如:
2^10 = 2^5 * 2^5
2^5 = 2 * 2^4
2^4 = 2^2 * 2^2
2^2 = 2^1 * 2^1
2^1 = 2 * 2^0
二、递归式
通过奇数,偶数时的不同情况
typedef long long ll;
ll binaryPow(ll a, ll b, ll m){
if(b == 0)
return 1;
else if(b % 2 == 1) //或(b&1)执行速度更快 判断是否为奇数
return a * binaryPow(a, b - 1, m) % m;
else{
ll num = binaryPow(a, b/2, m) % m; //优化
return num * num % m; // 不直接写成return binaryPow(a, b/2, m) * binaryPow(a, b/2, m)
}
}
三.例题
1. 统计好数字的数目(题目)
我们称一个数字字符串是 好数字 当它满足(下标从 0 开始)偶数 下标处的数字为 偶数 且 奇数 下标处的数字为 质数 (2,3,5 或 7)。
比方说,"2582" 是好数字,因为偶数下标处的数字(2 和 8)是偶数且奇数下标处的数字(5 和 2)为质数。但 "3245" 不是 好数字,因为 3 在偶数下标处但不是偶数。
给你一个整数 n ,请你返回长度为 n 且为好数字的数字字符串 总数 。由于答案可能会很大,请你将它对 109 + 7 取余后返回 。
一个 数字字符串 是每一位都由 0 到 9 组成的字符串,且可能包含前导 0 。
示例1:
输入:n = 1
输出:5
解释:长度为 1 的好数字包括 “0”,“2”,“4”,“6”,“8” 。
示例2:
输入:n = 4
输出:400
示例3:
输入:n = 50
输出:564908303
2.代码
typedef long long ll;
const int MOD = 1e9 + 7;
ll f(ll a,ll b){
ll res = 1; //初始令 res = 1,用来存放累积的结果
while(b){ //b!=0即b>0就一直执行循环
if(b & 1) //b%2==1
res = res * a % MOD; //判断b的二进制末尾是否为1,或理解为判断b是否为奇数。如果是的话,令res乘上a的值。
a = a * a % MOD; //令a平方,并使b右移一位
b >>= 1; //b/2
}
return res;
}
int countGoodNumbers(long long n){
return f(5 , (n + 1) / 2) * f(4 , n / 2) % MOD;
}