快速幂
求
a
n
a^n
an,一般的做法是循环
n
n
n次,每次给答案乘上
a
a
a。
但如果想要快速求出
a
n
a^n
an的值,而
n
≤
1
0
18
n≤10^{18}
n≤1018,怎么办?
先看一下幂的基本性质
1、
a
m
∗
a
n
=
a
m
+
n
a^m*a^n=a^{m+n}
am∗an=am+n
2、
(
a
m
)
n
=
a
m
n
(a^m)^n=a^{mn}
(am)n=amn
由此可以发现以下规律:
当
n
n
n为偶数时:
a
n
=
a
n
2
∗
2
=
(
a
n
2
)
2
a^n=a^{\frac{n}{2}*2}=(a^{\frac{n}{2}})^2
an=a2n∗2=(a2n)2
当
n
n
n为奇数时:
a
n
=
a
n
−
1
2
∗
2
+
1
=
(
a
n
2
)
2
∗
a
a^n=a^{\frac{n-1}{2}*2+1}=(a^{\frac{n}{2}})^2*a
an=a2n−1∗2+1=(a2n)2∗a
我们能发现什么
计算乘方时,其实有很多重复的运算,计算时可以通过上面的两条规律来得出。
这就是所谓的快速幂的思想!!!
怎么实现
使用递归,每次判断
n
n
n的奇偶性,然后递归下去,回溯求值。
边界条件:
a
0
=
1
a^0=1
a0=1
代码
#include<cstdio>
using namespace std;
int count(int x,int n)
{
if(n==0) return 1;
else
{
int s=count(n/2);
if(n%2==0) return s*s; else return s*s*x;
}
}
int main()
{
int a,n;
scanf("%d%d",&a,&n);
printf("%d",count(a,n));
return 0;
}