题目地址:HDU 1757
终于会构造矩阵了。其实也不难,只怪自己笨。。= =!
f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10)
构造的矩阵是:(我代码中构造的矩阵跟这个正好是上下颠倒过来了)
|0 1 0 ......... 0| |f0| |f1 |
|0 0 1 0 ...... 0| |f1| |f2 |
|...................1| * |..| = |...|
|a9 a8 .......a0| |f9| |f10|
然后根据矩阵的结合律,可以先把构造的矩阵的(k-9)次幂求出来。最后直接求第一个数。
代码如下:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #include <set> #include <algorithm> using namespace std; int mod, a[20]; struct matrix { int ma[20][20]; } init, res, s; matrix Mult(matrix x, matrix y) { int i, j, k; matrix tmp; for(i=0; i<10; i++) { for(j=0; j<10; j++) { tmp.ma[i][j]=0; for(k=0; k<10; k++) { tmp.ma[i][j]=(tmp.ma[i][j]+x.ma[i][k]*y.ma[k][j])%mod; } } } return tmp; } matrix Pow(matrix x, int k) { matrix tmp; int i, j; for(i=0; i<10; i++) for(j=0; j<10; j++) tmp.ma[i][j]=(i==j); while(k) { if(k&1) tmp=Mult(tmp,x); x=Mult(x,x); k>>=1; } return tmp; } int main() { int k, x, i, j; while(scanf("%d%d",&k,&mod)!=EOF) { if(k<10) { printf("%d\n",k%mod); continue ; } for(i=9; i>=0; i--) { a[i]=9-i; } for(i=0; i<10; i++) { scanf("%d",&x); init.ma[0][i]=x%mod; } for(i=1; i<10; i++) { for(j=0; j<10; j++) { init.ma[i][j]=(i==j+1); } } res=Pow(init,k-9); /*for(i=0; i<10; i++) { for(j=0; j<10; j++) { printf("%d ",res.ma[i][j]); } puts(""); }*/ int ans=0; for(j=0; j<10; j++) { ans=(ans+res.ma[0][j]*a[j])%mod; //printf("%d %d %d\n",res.ma[i][j],a[i],ans); } printf("%d\n",ans); } return 0; }
HDU 1757 A Simple Math Problem(矩阵快速幂)
原文地址:http://blog.csdn.net/scf0920/article/details/39351085