第31章 數論演算法 元素的冪以及模取冪

2021-07-11 23:22:42 字數 2151 閱讀 7428

在這裡介紹求元素的冪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...