1. 程式人生 > 其它 >優漫動遊如何進行角色原畫設計?具體分九個步驟

優漫動遊如何進行角色原畫設計?具體分九個步驟

本文將通過一個問題: 求 a^b%m 來介紹快速冪演算法。

我們首先來看一個問題:

給定三個正整數a,b,m(a<10^9, b<10^18, 1<m<10^9),求 a^b%m。

如果用迴圈來寫,不斷乘上a再取模,時間複雜度為O(b)。很容易超時。

所以我們考慮快速冪演算法。它基於二分的思想,也被稱為二分冪

遞迴寫法

1.如果b是奇數,那麼有:\(a^b = a*a^{b-1}\)

2.如果b是偶數,那麼有:\(a^b = a^{b/2}*a^{b/2}\)

typedef long long LL;
// 遞迴求a^b%m
LL binaryPow(LL a,LL b,LL m){
    if (b == 0) return 1;

    if (b%2 == 1) return a * binaryPow(a,b-1,m) % m;
    else{
        LL mul = binaryPow(a,b >>1,m);
        return mul * mul % m;
    }
}
  • 如果初始時a>=m,需要執行函式時先對a%m。
  • 如果m==1,直接在函式外部特判為0。

迭代寫法

把b寫成二進位制的形式,那麼b可以寫成若干二次冪之和。

例如13的二進位制形式為1101, \(13=2^3+2^2+2^0,a^{13}=a^8\ *a^4\ *a^1\)

不難推出:當b的二進位制的第i(從0開始)位是1時,初值ans=1要乘上\(a^{2{^i}}\)。由於我們每次迭代時令a平方

\(a=a^{2i}\)),所以列舉當前第i位時,a已經迭代到初始a的\(2^i\)次方,如果是1,就令ans乘上a。

typedef long long LL;
//  迭代求a^b%m
LL binaryPow(LL a,LL b,LL m){
    LL ans = 1;
    while (b > 0){
        // 等價於b%2 == 1
        if (b&1) ans = ans*a%m;
        a = a*a%m;
        b >>1;
    }
    return ans;
}

在實際應用場景,兩種寫法效率差不多。

大數取模公式總結:

參考資料1:部落格園

參考資料2:《演算法筆記》