在這裡介紹求元素的冪x^n(x和n均為非負整數)的兩種演算法,乙個是遞迴求解,另外乙個是用反覆平方法
當我們計算x^n時,當n=0,結果為1,這可以看做遞迴的基準情況,當n為偶數時,x^n=(x^2)^(n/2),當n是基數時,x^n=(x^2)^((n-1)/2)*x。**如下:
bool iseven(unsigned
int n)
unsigned
long
pow(unsigned
long x,unsigned
int n)
不難得出,遞迴求解元素冪的時間複雜度為o(log n).
我們是要求x^n,假設n可以用二進位制表述出來,即n(k-1)…n(0)(n(i)=0或1),則n=2^(k-1)* n(k-1)+…+2^0* n(0);
這樣的話,x^n=x^(2^0* n(0))* x^(2^1* n(1))…. *x^(2^k n(k))
我們迭代k次,即可得出x^n。不難得出k=o(log n),所以反覆平方法的時間複雜度為o(log n)。**如下:
unsigned
long
pow(unsigned
long x,unsigned
int n)
return ret;
}
模取冪是計算(a^b)%c這類問題(a,b 為非負整數,c為正整數),在這裡介紹三種計算模取冪的三種演算法。
模運算具有這樣的性質:(m*n)%d= ((m%d)*n)%d
所以a^b%c可寫成((((((1*a)%c)*a)%c)*a)%c…*a)%c(有b個a)。因此依據這個等式,可以寫成如下**:
unsigned
long mod_1(unsigned
long a, unsigned
long b, unsigned
long c)
模運算除了上面說的具有(m*n)%d= ((m%d)*n)%d這樣的性質外,還具有這樣的性質:當n
=n1∗
n2∗n
3∗..
.∗nn
,(nm
odm)
=[1∗
(n1m
odm)
∗(n2
modm
)∗(n
3mod
m)∗.
..(n
nmod
m)]m
odm
把上面兩個性質結合在一起的話,n mod m可以寫成如下形式: (n
modm
)=((
((((
1)∗(
n1mo
dm))
modm
∗(n2
modm
)))m
odm∗
(n3m
odm)
)mod
m...
∗(nn
modm
))mo
dm並且 if
ni=n
i−1∗
ni−1
,(ni
modm
)=mo
dm當我們計算a^b%c時,b可以寫成如下的形式:
b=p(0)*2^0+ p(1)*2^1+…p(i)*2^i+…+p(n-1)*2^n-1 (p(i)=0 or 1)
則a^b可以寫成如下形式:
a^b=a^(p(0) * 2^0))* ..* a^(p(i) * 2^i) * … * a^(p(n-1)*2^n-1)。因此求解a^b%c的**可以寫成如下形式:
unsigned
long mod_2(unsigned
long a, unsigned
long b, unsigned
long c)
return ret;
}
第三種演算法也就是第二種演算法的遞迴版本,**如下:
unsigned
long mod_2recursive(unsigned
long a,unsigned
long b,unsigned
long c)
快速冪和快速冪取模的演算法
後話基本原理請參見遞迴形式的 快速冪的非遞迴形式 long long int mi long long int a,int b return sum 快速冪的遞迴形式 long long int mi int a,int b 這裡涉及的原理除了快速冪之外,還涉及到我現在數學沒學到的乙個定理 多個數的...
快速冪(冪運算取模的logn演算法)
以下以求a的b次方來介紹 把b轉換成二進位制數 該二進位制數第i位的權為 例如11的二進位制是1011 11 2 1 2 0 2 1 2 1 因此,我們將a 轉化為算 對於 令a 0 a 2 0 1 a 1 a 2 1 1 a 2 a 2 2 0 a 3 a 2 3 1 可以看出a n 的前半部分是...
簡單易懂的快速冪取模演算法
請設計乙個演算法求x的y次冪模z的結果 x y z 由於x y的絕對值可能很大,x y的結果可能會溢位。所以先求x y,再對z取模,顯然是不現實的。這裡要借助模運算的一條運算規則 根據上面的推導,就可以很容易寫出 實現 int powmod int x,int y,int z else int po...