FZU_1683 矩阵快速幂 求和
这个题目确实是很简单的一个矩阵快速幂,但是我在求和的时候,用的是标准的求和,即,一共计算logN次Ak,但是这样会超时。
后来就发现原来本身和Sn=Sn-1+Fn;即Sn本身可以写在矩阵当中,所以直接求一次 Ak就能得出结果。
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> using namespace std; struct Mat{ int mat[4][4]; }; Mat it,E,E0; void init() { memset(it.mat,0,sizeof (Mat)); memset(E.mat,0,sizeof (Mat)); memset(E0.mat,0,sizeof (Mat)); for (int i=0;i<4;i++) E.mat[i][i]=1; it.mat[0][0]=1; it.mat[0][1]=3; it.mat[0][2]=2; it.mat[0][3]=7; it.mat[1][1]=3; it.mat[1][2]=2; it.mat[1][3]=7; it.mat[2][1]=1; it.mat[3][2]=1; } Mat operator*(Mat a,Mat b) { Mat c; c=E0; for (int i=0;i<4;i++) for (int j=0;j<4;j++) for (int k=0;k<4;k++) { if (a.mat[i][k] && b.mat[k][j]) { c.mat[i][j]+=a.mat[i][k]*b.mat[k][j]; c.mat[i][j]%=2009; } } return c; } Mat operator^(Mat a,int x) { Mat c=E; for (;x;x>>=1) { if (x&1) c=c*a; a=a*a; } return c; } int main() { init(); int t; scanf("%d",&t); int counts=0; while (t--) { int n; scanf("%d",&n); int ans=0; printf("Case %d: ",++counts); if (n>=3){ Mat s=it^(n-2); ans=s.mat[0][0]*9+s.mat[0][1]*5+s.mat[0][2]*3+s.mat[0][3]; ans%=2009; } if (n==0) ans=1; if (n==1) ans=3; if (n==2) ans=5; printf("%d\n",ans); } return 0; }