[模板]快速幂

快速幂模板:

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为指数).

 

posted @ 2020-12-25 20:26  goverclock  阅读(88)  评论(0编辑  收藏  举报