P1226 【模板】快速冪||取餘運算
阿新 • • 發佈:2020-12-25
快速冪模板:
int ksm(int b, int p, int k){ int ans = 1 % k; while(p){ if(p & 1) ans = (long long)ans * b % k; b = (long long)b * b % k; p >>= 1; } return ans; }
思想是將指數p分解為二進位制處理.由於結果數值經常很大,題目一般只要求給出取模後的答案.
而取模具有傳遞性,至少在只進行加減乘運算時,過程中何時取模,取多少次模都不會影響最終答案,前提是過程中不發生溢位.
注意這裡取模物件是int,故取模後一定是int範圍內的數值,但是要注意int與int相乘是會越過int範圍的,需要先進行(long long)強制轉換,取模後範圍變回int再賦值.
具體分析:
將p分解為:
p=a020+a121+a222+a323+...+ak-12k-1,(p轉化為二進位制表示有k位)其中,ai=0或1,
則bp=ba02^0*ba12^1*ba22^2* ... *bak-12^(k-1).所以設ans為1,從最低位開始對p的每一位進行處理,若該位為1,則ans乘以左式對應的乘積項.位為0對應的乘積項顯然都變為了1,不需要相乘.
發現在忽略ai的情況下,一個乘積項總是上一個乘積項的兩倍,因此設定一個變數記錄這個以2累乘的過程值便於計算.
複雜度分析:
上述過程的while迴圈進行了log p次,即複雜度為O(log n).這是比一遍遍地累乘原數值要快的(O(p),p為指數).