題目連結:hdu 2035 人見人愛A^B
很早的時候做的一道題了,今天想想把他翻了出來,寫篇文章來為不知道快速冪的同學做一個科普(請允許我吹一下牛逼)。快速冪可以高效的計算冪運算。如果我們使用迴圈來計算的話,那麼時間複雜度就是 O(n) ,使用快速冪的話就只用 O(log n)。不要小看這麼一點點,如果一個問題需要多次 的 冪運算的話,可能就會因為這一點小小的變化而逾時。
快速冪介紹:
我們一直說快速冪快,那他究竟是在哪裡快呢? 如果我們求解 2^k。可以將其表示為
x^n =( (x²)²....)
只要做k次平方運算就可以了,由此我們可以想到,先將n表示為2的冪方次之和
n = 2^k1 + 2^k2 + 2^k3.......
就有
x^n = x^(2^k1) x^(2^k2) x^(2^k3).......
So.快速冪就是這麼快。不太明白的可以用筆和紙手動的類比一下。
例如: x^22 = x^16·x^4·x^2
快速冪的模板:
typedef long long ll; //注意這裡不一定都是long long 有時 int 也行ll mod_pow(ll x, ll n, ll mod){ ll res = 1; while( n > 0 ){ if( n & 1 ) res = res * x % mod; //n&1其實在這裡和 n%2表達的是一個意思 x = x * x % mod; n >>= 1; //n >>= 1這個和 n/=2表達的是一個意思 } return res;}
沒看位元運算的童鞋,好好回去看看,好多地方都是用這東西
遞迴版的:
typedef long long ll;ll mod_pow(ll x, ll n, ll mod){ if( n == 0 ) return 1; ll res = mod_pow( x * x % mod, n / 2, mod ); if( n & 1 ) res = res * x % mod; return res;}
下面附上本題的代碼:
#include<stdio.h>int mod_pow(int x, int n,int mod){ //快速冪 int res = 1; while( n > 0 ){ if( n & 1 ) res = res * x % mod; x = x * x % mod; n >>= 1; } return res;}int main(){ int m,n; while(scanf("%d%d",&m,&n),n||m) printf("%d\n",mod_pow(m,n,1000)); return 0;}
快速冪延伸:矩陣快速冪
(如有錯誤,歡迎指正,轉載請註明出處)