快速冪基本性質和一些優化寫法

2021-10-09 21:31:40 字數 1610 閱讀 6610

求 a^b % m的值,時間複雜度o(b)

利用for來寫,每一次迴圈都 mod m (利用模運算—>可在**首頁搜尋"模運算"了解同模運算加減乘除定理)

結果:b接近於10億時,計算機運算時間接近於18秒

前言:我們知道,3^4= 3^2 * 3^2 = 3^1 * 3^1 * 3^1 * 3^1 ;

那麼我們如果先將32的值計算出來,儲存在臨時變數p中,那麼此時,34中需要計算的量就為:

3^4=3^2* 3^2 =3^1* 3^1 * 3^1 * 3^1 ;–>只計算了兩次

此時a^b運算的時間複雜度 從o (b) 變為了 o (logb)

實現方式,遞迴思想;

注意點:當出現3^5這種指數為奇數的情況時,我們可以寫成 3^1 * 3^4 的形式,即當ab,b為奇數時,我們將其寫成a(b-1) * a 的形式

遞迴**:

typedef long long ll;

int ans;

int quick_pow(int base,int power,int mod)//base為底數,power為指數

}

如何將遞迴形式簡化寫成while()形式:

我們知道 例如3^8= 3^4 * 3^4 其實可以寫成 38=(34)2=(32)4,即當ab,b為偶數時,我們可以寫成(a2)(b/2),將上述的quick_pow(base,power/2,mod) * quick_pow(base,power/2,mod),簡化為,a=a * a後,令b/=2;

且當b為奇數時,a^b=a * a^(b-1)—>這個a並不是初始的底數而是當前的a,將此時的a用ans=ans * a將其「收集」起來,而最終,b為1時,也會有ans=ans * a,所以最終ans為答案

舉例:a^7=a * a^6=a * (a2)3 =a * a^2 * (a2)2=… 其中 其一步 ans將 a 收集起來 第二步 將 a^2 收集起來…

while()形式**:

int quick_pow(ll base,ll power,int mod)

return ans;

}

注意這裡利用了位運算&,在這裡的作用為判讀奇偶。

為什麼使用位運算:位運算消耗的時間更短。

位運算的其他用法請參考:

例:a ^13 = a^1 * a^4 * a^8,是因為13的二進位制 1101。

所以我們可以將a^b 表示成 ∏a(2符合條件的i) (∏為連乘)。若b二進位制中i+1位為1則符合條件。

且由於每進一位,a->a2->(a2)^2->。。。

所以我們可以先定義乙個ans,從b的二進位制第一位(最右邊)開始,若a&b為1,則說明,這一位為1,那麼ans * =a,否則,不乘,進入下一位,實行操作a=a * a b>>=1; 直到b取盡。

**

int quick_pow(ll base,ll power,int mod)

return ans;

}

如此一來,進一步降低了複雜度,使得快速冪更加高效。

單調棧的介紹以及一些基本性質

單調棧就是棧內元素單調遞增或者單調遞減的棧,單調棧只能在棧頂操作。為了更好的理解單調棧,則可將單調棧用生活情形模擬實現,例如 我們借用拿號排隊的場景來說明下。現在有很多人在排隊買可樂,每個人手裡都拿著號,越靠前的人手裡的號越小,但是號不一定是連續的。小明拿了號後並沒有去排隊,而是跑去約會了。等他回來...

凸優化的一些基本概念

函式任意兩點連線上的值 大於 對應自變數出的 函式值 的函式 在凸函式任何點畫一條切線,在這條線上的每個點都將小於在函式f上的點 目標函式是凸函式,變數所屬集合是凸集合的優化問題 1 線性規劃 linear program,lp 目標函式和約束函式都是線性的 2 二次規劃 quadratic pro...

關於排列數和組合數的一些性質

從 n 個不同元素種取出 m m le n 個元素的所有不同排列的個數,叫做從 n 個不同元素種取出 m 個元素的排列數,用符號 a n m 表示。排列數的一些性質 a n m frac na frac frac a n m ma a m frac frac frac frac a n m 從 n ...