快速幂/欧拉降幂

快速幂

  • 介绍

    所谓快速幂就是在可以在 $ O(\log{k})$ 的时间复杂度内求得\(x^k\ \ mod\ \ p\)的结果。

    我们知道常规的算法求幂需要 \(O(k)\)的复杂度。

    int res = 1;
    for(int i = 1; i <= k; i++)
    {
        res = res * a mod p;
    }
    
  • 核心思想:反复平方

    首先,我们都知道任意一个十进制的数k都可以转换为\(2^{i_1}+2^{i_2}+2^{i_3}+...+2^{i_t}\)这样的形式。

    那么\(a^k\) 一定可以写成 \(a^{2^{i_1}+2^{i_2}+2^{i_3}+...+2^{i_t}}\)这样的形式。

    进而求解\(a^k \ \% \ p\) 实际上就是求\((a^{2^{i_1}+2^{i_2}+2^{i_3}+...+2^{i_t}} )\% \ p\)

    又由取模运算规则

    \[(a+b)\%p = (a\%p + b\%P)\%p\\(a-b)\%p = (a\%p - b\%P)\%p\\(a*b)\%p = (a\%p * b\%P)\%p\\a^b \ \% \ p = ((a \% p)\ ^b)\ \% \ p \\....\\
    \]

    \((a^{2^{i_1}+2^{i_2}+2^{i_3}+...+2^{i_t}} )\% \ p = (a^{2^{i_1}} * a^{2^{i_2}} *a^{2^{i_3}} *a^{2^{i_t}}) \% \ p = ..\)

    利用乘法的模运算规则,迭代即可。

    所以关键的问题就是把k转换为\(2^{i_1}+2^{i_2}+2^{i_3}+...+2^{i_t}\)这样的形式。

    关于代码:一共迭代\(\log{k}\)

    \[a^{2^0} \quad mod \quad p\\
    a^{2^1} \quad mod \quad p\\
    a^{2^2} \quad mod \quad p\\
    a^{2^3} \quad mod \quad p\\
    a^{2^4} \quad mod \quad p\\
    .\\
    .\\
    a^{2^{\log{k}}} \quad mod \quad p
    \]

    其中显然可知:\(a^{2^{i+1}}\) = \(a^{2^{i} * 2}\) = \(({a^{2^{i}}})^2\)

    代码模板

    //a^k mod p
    int qmi(int a,int k, int p)
    {
        int res = 1;
        while(k)
        {
            if(k & 1) res = (LL)res * a % p;
            k >> 1;
            a = (LL)a * a % p;
        }
        return res; 
    }
    

欧拉降幂

原文链接: https://www.cnblogs.com/keepyang/p/12494705.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    快速幂/欧拉降幂

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/335358

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月1日 下午10:07
下一篇 2023年3月1日 下午10:07

相关推荐