用暴力求幂,时间复杂度为O(n)(代码都会了吧,这都不会不要往下看了,洗洗睡吧)
但是当(设底数为a,次数为b)b较大时,即使a较小,时间也不能让人接受,如b=时,时间复杂度为O(10^11),显然,这是不能被接受的。
此时,则需要——快速幂,时间复杂度仅仅为O(logn)!!!!!!!!!!!!!
一个非常基本的定理:
不会有人不懂吧,举个例子x=2,a=4,b=3,
我们可以分解一下
发现了吗,当分解数的指数为偶数时
否则为奇数
(“/” 表示整除)。
一个递归可以很直观看懂:
function ksm(a,b:longint):longint;
var t:longint;
begin
if b mod 2=0 then
begin
t:=ksm(a,b div 2);// 这里求了一次,而下面利用t直接求值,这保证了O(2*logn)变为O(logn)
ksm:=t*t;
end
else
begin
t:=ksm(a,b div 2);
ksm:=t*t*a;
end;
end;
众所周知,递归基本不会 不稳定,所以我们可以改为循环
ans:=1;
while b>0 do
begin
if b mod 2=1 then ans:=ans*a;//多余的先计入ans
a:=a*a;
b:=b div 2;
end;
希望帮到大家。