快速幂
当需要做大量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
(若有错误,请及时指出,万分感谢!)