演算法 快速冪

2022-01-12 19:18:28 字數 1188 閱讀 4298

求底數為a的n次冪:

一般解法都是「a*a*a……*a」,複雜度為o(n);

1.把n轉換為二進位制,例如:

11轉換為二進位制1011;

2.將n得到的二進位制以「數字的值*權值」的和表示,例如:

11可表示為「1*(2^3)+0*(2^2)+1*(2^1)+1*(2^0)」;

3.由第2點可以得到a的11次方為:

a^(1*(2^3))*a^(0*(2^2))*a^(1*(2^1))*a^(1*(2^0));

那麼就可得以下**(下面的**將結果取模了,因為一般的運算結果過於龐大,題目或者實際都是要求是將結果取模,如果不需要取模自行刪除即可),時間複雜度是o(log2n):

1 #include2

using

namespace

std;

3int main()//

計算a^n % mod

413 n >>= 1;//

移位操作,去掉n的最後一位

14 a = (a * a) %mod;

15/*

這裡用了乙個技巧,a*a即求出了a^(2^(i-1))

16*不知道這是什麼的看原理

17*a^(2^(i-1))*a^(2^(i-1))=a^(2^i)

18*而且一般情況下a*b mod c =(a mod c)*(b mod c) mod c

*/19

}20 cout<< re %mod;

21return0;

22 }

需要注意的是,可能很多人都看不懂14行的含義:

a = (a * a) % mod;

不理解的話就只能是生搬硬套的模板,沒有任何意義。雖然**注釋裡都說了,但是還是得講一下自己的理解,我也怕以後忘記了,還是以a的11次方為例:

由於n的二進位制的數字的值只會是1和0,因此上面第3點得到的式子中的1省去,有:

a^(1*(2^3))*a^(0*(2^2))*a^(1*(2^1))*a^(1*(2^0))  =>  a^(2^3) * a^(0*(2^2)) * a^(2^1) * a^(2^0)

看到上式2的指數,那麼注釋裡的 「a^(2^(i-1))*a^(2^(i-1))=a^(2^i)」 是不是就清晰易懂了呢?

演算法提高快速冪(快速冪演算法詳解)

問題描述 給定a,b,p,求 a b mod p。輸入格式 輸入共一行。第一行有三個數,n,m,p。輸出格式 輸出共一行,表示所求。樣例輸入 2 5 3 樣例輸出 資料規模和約定 共10組資料 對100 的資料,a,b為long long範圍內的非負整數,p為int內的非負整數。所謂的快速冪,實際上...

快速冪演算法

在 上一直沒有找到有關於快速冪演算法的乙個詳細的描述和解釋,這裡,我給出快速冪演算法的完整解釋,用的是c 語言,不同語言的讀者只好換個位啦,畢竟讀 c的人較多 所謂的快速冪,實際上是快速冪取模的縮寫,簡單的說,就是快速的求乙個冪式的模 餘 在程式設計過程中,經常要去求一些大數對於某個數的餘數,為了得...

快速冪演算法

模運算 公式 a b mod n a mod n b mod n mod n a b mod n a mod n b mod n mod n a b mod n a mod n b mod n mod n 要保證n是整數 要知道a mod n和b mod n都是比n小的 利用這些共識可以有效地防止溢...