快速冪的目的就是做到快速求冪,假設我們要求a^b,按照樸素算法就是把a連乘b次,這樣一來時間復雜度是O(b)也即是O(n)級別,快速冪能做到O(logn),快了好多好多。它的原理如下:
假設我們要求a^b,那么其實b是可以拆成二進制的,該二進制數第i位的權為2^(i-1),例如當b==11時
a^11=a^(2^0+2^1+2^3)
11的二進制是1011,11 = 23×1 + 22×0 + 21×1 + 2o×1,因此,我們將a11轉化為算 a^(2^0)*a^(2^1)*a^(2^3) ,看出來快的多了吧原來算11次,現在算三次,但是這三項貌似不好求的樣子….不急,下面會有詳細解釋。
由于是二進制,很自然地想到用位運算這個強大的工具: & 和 >>
&運算通常用于二進制取位操作,例如一個數 & 1 的結果就是取二進制的最末位。還可以判斷奇偶x&1==0為偶,x&1==1為奇。
>>運算比較單純,二進制去掉最后一位。
現在已上邊的式子為例:
int powx(int a,int b)
{int ans=i,base=a;while(b!=0){if(b&1)ans*=base;base*=base;b>>=1;}return ans;
}
代碼很簡單,但還是要理解。
解釋級就自己當初不懂得:
base*=base;
這個是完全為了達到累乘的效果,例如上題,這個就相當于把a^11變成了a^(2^0),a^(2^1),a^(2^3);
另一種詳細的解釋:
其中要理解base*=base這一步,base*base==base^2,下一步再乘,就是base^2*base^2==base^4,然后同理 base^4*base4=base^8,,,,,see?是不是做到了base–>base^2–>base^4–>base^8–>base^16–>base^32…….指數正是 2^i 啊,再看上 面的例子,a11= a^(2^0)*a^(2^1)*a^(2^3),這三項是不是完美解決了,,嗯,快速冪就是這樣。