快速幂

当需要做大量a^b的计算时,用for循环累乘的时间复杂度为O(n),如遇到类似百度之星资格赛ProblemA http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=690&pid=1001 这样的数据时,一定会超时的。

观察可以发现,a^b不就是a*a*a*a...a*a*a*a嘛,把a^b/2算出来再对其结果平方不就得出结果了么,而时间居然减少了一半,好神奇诶←.←。

依据这个结论,又可以将前半段继续二分,直到不能再分。是不是很符合递归思想呢?

那我先给出递归实现的代码好了:

//坚决不要用,谁用谁ZZ(来自不小心使用结果炸裂的ZZ)
int
fastMi(int a,int b){ int k,mut=1; if(b==0) return 1; k=a*a; if(b%2!=0) mut*=a; mut*=fastMi(k,b/2); return mut; }

然而当b比较大的时候,递归的效率不是很高,而且函数栈还有爆掉的危险。

所以以下给出循环实现的代码:

LL fastMi(LL a,LL b)
{
    a%=mod;
    LL mut=1;
    while(b)
    {
        if(b%2!=0)
            mut*=a,mut%=mod;
        a*=a,a%=mod;
        b/=2;
    }
    return mut%mod;//考虑极端情况mod=1
}

掌握快速幂后,把其中的a替换成以结构体定义的矩阵,就可以实现矩阵快速幂了,至于是在这篇博客里补充还是另外写一篇,待我挖个坑先2333

(若有错误,请及时指出,万分感谢!)

原文地址:https://www.cnblogs.com/LukeStepByStep/p/5535688.html