算法思想
任何一个大于零的整数都可以展开成:
I
=
∑
k
=
0
∞
P
k
×
2
k
,
P
k
=
0
,
1
I = \sum_{k=0}^{\infty}P_{k} \times 2^{k},P_{k}= 0,1
I=k=0∑∞Pk×2k,Pk=0,1
如果将指数按照上式展开,那么幂可以表示成:
M
=
∏
k
=
0
∞
B
P
k
×
2
k
,
P
k
=
0
,
1
M = \prod_{k=0}^{\infty} B^{P_{k} \times 2^{k}},P_{k}=0,1
M=k=0∏∞BPk×2k,Pk=0,1
因此可以把累计相乘拆分成多个循环,其中
B
2
k
B^{2^{k}}
B2k 可以由
B
2
k
−
1
B^{2^{k-1}}
B2k−1 平方后的得到,可以设置一个变量 j 来表示
B
2
k
B^{2^{k}}
B2k ,初始值为底数,而后每次循环都对自己求平方。设置变量 r 来表示幂,初始值为 1 ,每次循环都判断
P
k
P_{k}
Pk 的值,若为 1 则 r 乘以 j,否则跳过。
时间复杂度
由于 j 的存在时间复杂度由 Θ ( n ) \Theta(n) Θ(n) 简化到 Θ ( log 2 n ) \Theta(\log_2n) Θ(log2n)。
测试代码
#include <iostream>
using namespace std;
int main(){
int n,i;
cin >> n >> i;///读入底数和指数
int r = 1;///幂初始化为1
for(int j=n;i;j*=j){
if(i&1){
r *= j;
}
i >>= 1;///把指数拆分成2的幂的加和
}
cout << r << endl;
return 0;
}