二分快速幂
1 2 3 4 5 6 7 8 9 10 11 12 13
| long long doexp(int x,int y) { long long i=1,j=x; long long k; if (x==1||y==1) return x; while (y) { if (y&1) i=(i*j)%k; j=(j*j)%k; y=y>>1; } return i; }
|
利用了二分log(n)级的快速迭代平方运算,可以很高效地完成幂运算。
与数的乘幂相类似,矩阵乘法同样存在结合律,所以可以利用相同的方法加速运算,得到矩阵快速幂。
矩阵快速幂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| typedef struct matrixnod { int m[3][3]; } matrix;
matrix mat(matrix a,matrix b) { matrix c; int mod; for (int i=0;i<3;i++) for (int j=0;j<3;j++) { c.m[i][j]=0; for (int k=0;k<3;k++) c.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod; c.m[i][j]%=mod; } return c; }
matrix doexpmat(matrix b,int n) { matrix a= { 1,0,0, 0,1,0, 0,0,1 }; while(n) { if (n&1) a=mat(a,b); n=n>>1; b=mat(b,b); } return a; }
|
形式上来说跟普通的二分快速幂相同
对于这一类题目,解题的核心就在于如何给出一个可行的矩阵来将初始状态推到最终需要的结果上。
这里可以采用DP等思路来把(状态转移)矩阵给推出来,话说DP优化里面本来也就有一项是矩阵优化……殊途同归啊