1. 程式人生 > >快速冪演算法及其拓展

快速冪演算法及其拓展

摘要

本文講解了快速冪演算法的定義、複雜度證明及兩種實現(遞迴與非遞迴),以及它的兩個重要拓展:快速冪模M演算法和矩陣快速冪。其中矩陣快速冪演算法是矩陣求冪問題對整數求冪問題的借鑑,實際應用中對於線性遞推式求解能起到強大的效率優化。

快速冪演算法

問題引入:求an(a,nN+)
樸素演算法:令ans初始值為1,乘n次a得到an
樸素演算法時間複雜度:O(n)

問題:如果n非常大,比如高達1015,怎麼辦?
思考:樸素演算法哪裡可以優化?

樸素演算法的特點是,連乘過程中底數始終為a,這很不聰明。考慮下例:
a=2,n=15
我們沒有必要乘15次2,注意到15=23+2

2+21+20,不妨將215拆分為223×222×221×220
然後看一下n的二進位制形式:15=(1111)2.為什麼要看這個呢?再舉一個例子。

a=2,n=6
26=222×221,而6=(110)2

發現什麼規律?
觀察發現,當n的第i位(從低到高,i>=0)為1時,an的拆解表示式裡就要乘上一項a2i.

於是我們有了樸素演算法改進的思路:逐位判斷冪次n的二進位制位是否為1,若是,給答案乘上一個a2i.
改進後的演算法的虛擬碼描述如下:

a, n, ans;
ans=1;
while n>0
    a = a*a;
    if n%2
        ans = ans
*a; n = n/2;

這個演算法的時間複雜度是多少呢?很顯然,它取決於n的二進位制形式有多少位,因此T(n)=log2(n)=O(logn).這就是快速冪演算法。

其實快速冪演算法還可以遞迴實現,因為:
當n為偶數時,an=(an/2)2
當n為奇數時,an=(an/2)2×a
邊界條件:當n=1,答案為a
C語言描述如下:

int quick_power(int a, int n)
{
    if(n == 1) return a;
    int x = quick_power(a, n/2);
    long long ans = (long long)x*x;
    if
(n%2) ans *= a; return (int)ans; }

程式碼中加入了防溢位處理,用快速冪演算法的時候比較容易犯的一個錯誤就是忘了考慮溢位,因此在使用的時候要看清楚資料範圍,估算一下答案上界。另外,快速冪演算法不推薦用遞迴實現,因為非遞迴版本不但程式碼也很簡潔,而且效率還更優。

拓展一:快速冪模M演算法

有時候所求冪的結果可能很大,於是問題要求對結果模上一個數M。我們只需要在原來演算法的基礎上運用一下模運算的性質即可。所謂模運算性質是指以下兩條:
ni=1aimodM=(ni=1aimodM)modM
ni=1aimodM=(ni=1aimodM)modM
演算法非遞迴實現的虛擬碼描述為

a, n, ans, M;
ans=1;
while n>0
    a = a*a % M;
    if n%2
        ans = ans*a % M;
    n = n/2;

拓展二:矩陣快速冪演算法

快速冪演算法解決的是整數求冪的問題,而矩陣快速冪解決的是矩陣求冪問題,兩者沒有本質的區別。如果用C++實現,我們只要定義一個矩陣類,然後過載一下乘法運算子,原先的快速冪演算法幾乎不需要改變。
矩陣快速冪常常用於線性遞推式的加速。以下僅舉一例。

快速求斐波那契數列第n項

對於這個問題,普通求法的複雜度是O(n),現在我們用矩陣快速冪將它優化到O(logn).
首先,將遞推式f(n)=f(n1)+f(n2)改寫成矩陣形式

[f(n)f(n2)f(n1)f(n3)]=[f(n1)f(n3)f(n2)f(n4)][1110]
進而得到
[f(

相關推薦

快速演算法及其拓展

摘要 本文講解了快速冪演算法的定義、複雜度證明及兩種實現(遞迴與非遞迴),以及它的兩個重要拓展:快速冪模M演算法和矩陣快速冪。其中矩陣快速冪演算法是矩陣求冪問題對整數求冪問題的借鑑,實際應用中對於線性遞推式求解能起到強大的效率優化。 快速冪演算法

輾轉相除,二進位制一的個數,快速演算法使用遞迴的相同處

遞迴在演算法競賽中起到了很重要的角色,就這三個演算法進行一些歸納 輾轉相除法: //可以兩種遞迴的寫法,注意兩者的區別 int gcd(int a,int b) { return b==0?a:gcd(b,a%b); } int gcd(int a,int b) { if(b

關於快速演算法有效性的證明

在讀這篇文章之前,請確保已經完全明白二進位制基礎以及其他與本文相關的二進位制的知識 首先,假設我們要求,設a=3,b=101 將b轉化為二進位制表示,則為:1100101 通過二進位制基礎,我們知道:, 通過乘法原理,我們知道:, 因此,可以推出: 那

hdu1097A hard puzzle(快速演算法)

A hard puzzle 題目: Problem Description lcy gives a hard puzzle to feng5166,lwg,JGShining and Ignatius: gave a and b,how to know the a^b.everybo

第五次測試 A的B次方 快速演算法

lcy gives a hard puzzle to feng5166,lwg,JGShining and Ignatius: gave a and b,how to know the a^b.everybody objects to this BT problem,so lcy makes

單鏈表的快速排序演算法及其實現

今天聽同學面友錄說道單鏈表是否可以用快速排序演算法,想起自己面百度一面的時候面試官也面到這個問題,由於本人是個小菜鳥,所以花了一個下午的時間整理了一下。 演算法思想:對於一個連結串列,以head節點

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

問題描述   給定A, B, P,求(A^B) mod P。 輸入格式   輸入共一行。   第一行有三個數,N, M, P。 輸出格式   輸出共一行,表示所求。 樣例輸入 2 5 3 樣例輸出 2 資料規模和約定   共10組資料   對100%的資料,A, B為lon

快速演算法和大整數求模

** 1.快速冪的演算法** (1)當我們求一個數的n次方的的結果時,若直接選擇for迴圈,來累乘的話,效率很低,時間複雜度位O(n),而當我們選擇快速冪來計 算時,時間複雜度能達到O(logn),快了很多。快速冪

快速演算法(全網最詳細地帶你從零開始一步一步優化)

                快速冪演算法——帶你從零開始一步一步優化 目錄                 快速冪演算法

荷蘭國旗演算法及其拓展

一排木桶裡分別裝有紅白藍三色小球(分別用0,1,2表示),如何讓所有的'0'出現在前面,所有的'1'在中間,所有的'2'在最後。 要求:要求空間複雜度為O(1),只許遍歷一遍字串陣列。 之所以叫荷蘭國旗,是因為我們可以將紅白藍三色小球想象成條狀物,有序排列後正好組成荷蘭國旗

快速演算法程式碼

#include <stdio.h> long long PowMod(long long a,long long b,long long c)//快速冪 { long long answer = 1; a = a % c; while(b &

矩陣快速演算法+例題(HDU 5667 Sequence)

矩陣快速冪是ACM比賽中對於求遞推式能用到的模板,能實現O(N^3*logM)的複雜度,其中 N是矩陣階乘,M是要求的第幾項。 對於矩陣快速冪,首先的得知道單位矩陣 ⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪11⋮110⋮0⋯⋯⋱⋯10⋮1⎫⎭⎬⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪ 明顯

快速演算法(hdu) Rightmost Digit

快速冪演算法,顧名思義,就是進行冪運算,http://acm.hdu.edu.cn/showproblem.php?pid=1061 這是hdu經典的一道題,如果我在接下來的解析中寫的不好,也請大家指點。 hdu這道題,他要求我們算出每個正整數的個位數,

C/C++程式設計小練習 大數乘方(快速演算法實現)

將我之前的大數乘方的演算法做了些小優化,程式碼改動很小 快速冪演算法實現大數乘方,時間複雜度由O(n^3)降到O(n^2*logn) 快速冪演算法原理其實蠻簡單的,類似於二分法的思想,掃描指數n的二進位制形式,然後按照0或1做相應處理 #include <iostre

快速乘法、快速 演算法

參考: https://blog.csdn.net/maxichu/article/details/45459715 點選開啟連結快速乘法:快速計算a*b%mod的結果,對於大數直接乘可能會爆long long,用快速乘法每一步都取餘不會爆掉。實現原理是:對於乘數b來說,勢必

快速演算法及矩陣快速

Description 給定三個數A, B, K, 求 A的B次方除以K的餘數 。 Input 輸入只有一行,為三個正整數A(1 <= A <= 2000000000), B(1 <

快速演算法 取餘運算 a^b mod c

題目描述Description 輸入b,p,k的值,程式設計計算bp mod k的值。其中的b,p,k*k為長整型數(2^31範圍內)。 輸入描述Input Description b p k  輸出描述Output Description

雜湊演算法及其拓展

本篇是iOS逆向開發的遞進篇-關於雜湊演算法、數字簽名及對稱加密等,下面我們著重講解此內容,希望對大家有所幫助!!!    一、雜湊 1.1 基本內容 雜湊表也稱為散列表(Hash table),是根據關鍵碼值(key,value),直接進行訪問的資料結構。通過把關鍵碼對映到表中的一個位置

程式設計師必學:快速演算法

前陣子,有小夥伴在我B站的演算法教程底下留言 小夥伴們有任何疑問或者希望我講解任何內容,都可以在我的個人B站或公眾號(xmg_mj)留言哦,我會盡我最大能力、儘量抽時間去寫文章\錄視訊來回應大家。 關於快速冪 其實快速冪相關的問題,是參加演算法競賽(NOI、ACM等)的小夥伴必須要掌握的一小塊基礎內容。當

演算法筆記-快速

快速冪就是快速的求底數的整數次方,比起樸素的方法O(n)的時間複雜度,其時間複雜度是O(log2n)。這是很不錯的一個效率提升。 通常要求一個數X的Y次方,記做X^Y,樸素的計算方法是把X乘Y次得到這個結果。 而快速冪計算的過程是,對於指數Y進行奇偶性的判斷。為了方便解釋,