其他分享
首页 > 其他分享> > P1226 【模板】快速幂||取余运算

P1226 【模板】快速幂||取余运算

作者:互联网

快速幂模板:

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

 

标签:取模,乘积,int,复杂度,long,P1226,ans,取余,模板
来源: https://www.cnblogs.com/Gaomez/p/14132964.html