矩阵快速幂

来源:互联网 发布:如何成为首富 知乎 编辑:程序博客网 时间:2024/06/05 18:17

今天是ACM校内赛。虽然我没学过OI,没有退役的感觉,但很有可能之后就不打ACM了。
这里很感谢队友的帮助,过了2道题,有希望拿奖。

自己做的是F题,求(7+43)n的整数部分。
一下子想到初中数学竞赛,an=(7+43)n+(743)n是整数。
怎么证的?求出递推方程an+1=4anan1. 归纳法
那么怎么求呢?说来真是一段历史。
初中时我会递推地求,至少比硬算快,高中时我会求出用特征方程通项公式,厉害吧,现在的我,已然是程序员视角,会用矩阵快速幂。

初中的算法是O(n)的,高中是数学手段,计算机精度行不通,大学是O(logn),这是友好的。

何为快速幂,就是二分法,算分课讲过这个分治思想,但具体实现可以借助位运算。有些时候,算法的思想和具体实现有不小的差距。

matrix power(int n){    matrix ans=initial;    matrix c;    while(n){        if(n&1) ans=mult(ans,c);        n>>=1;        c=mult(c,c);    }    return ans;}   

可以参考这里
以及这里

算法的原理是显然的,降为对数级。
至于an递推转化为矩阵乘法,高代、代组、算分课都讲过。例子是Fibonacci。
我因为要偷懒,只写一个2级矩阵乘法的函数,就这样写了,事实上可以是个2级矩阵乘以列向量。

[an+1ananan1]=[anan1an1an2][4110]=[a2a1a1a0][4110]n1

于是写个矩阵乘法,即可矩阵快速幂。
通常需要取模运算,就每一步对元素取模,如果是负数,可加上模数,以及long long是最后debug的关键。

码这题时我在想去年ACM室友说有一题是矩阵快速幂,忘了怎么写了,最后遗憾地放弃。于是一年里我一直记得快速幂,没想到今年又考到了,这是一种轮回。但不同的是,我进步了。