hdu1757 构造矩阵

Lele now is thinking about a simple function f(x).

If x < 10 f(x) = x.
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
And ai(0<=i<=9) can only be 0 or 1 .

Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.

构造一个矩阵

{

a0 a1 a2 a3 a4 a5 a6 a7 a8 a9

 1  0   0   0   0  0   0  0   0   0

 0  1   0   0   0  0   0  0   0   0

 0  0   1   0   0  0   0  0   0   0

 0  0   0   1   0  0   0  0   0   0

 0  0   0   0   1  0   0  0   0   0

 0  0   0   0   0  1   0  0   0   0

 0  0   0   0   0  0   1  0   0   0

 0  0   0   0   0  0   0  1   0   0

 0  0   0   0   0  0   0  0   1   0

}得解

#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
#include <math.h>
using namespace std;
typedef long long LL;
const int maxn=15;
int MOD;
struct Matrix
{
    LL m[maxn][maxn];
    Matrix mult(Matrix &rhs)
    {
        Matrix ans;
        for(int i=0; i<10; i++)
            for(int j=0; j<10; j++)
             {
                ans.m[i][j]=0;
                for(int k=0; k<10; k++)
                ans.m[i][j]=(ans.m[i][j]+(m[i][k]*rhs.m[k][j])%MOD )%MOD;

             }
       return ans;
    }
};
int a[10];
void powk(int n)
{
    Matrix A,ans;
    memset(ans.m,0,sizeof(ans.m));
    memset(A.m,0,sizeof(A.m));
    for(int i=0; i<10; i++){
        ans.m[i][i]=1;
        A.m[0][i]=a[i];
        A.m[i+1][i]=1;
    }
    while(n)
        {
             if(n&1)ans=ans.mult(A);
              n>>=1;
              A=A.mult(A);
        }
     LL AS=0;
     for(LL i=0; i<10; i++){
         AS=(AS+(ans.m[0][i]*(-i+9))%MOD )%MOD;
     }
     printf("%I64d\n",AS);
}
int main()
{
    int k;
    while(scanf("%d%d",&k,&MOD)==2)
    {
          for(int i=0; i<10; i++)scanf("%d",&a[i]);
          if(k<10){
            printf("%d\n",k%MOD); continue;
          }
          powk(k-9);
    }
    return 0;
}
View Code

 

posted @ 2015-09-14 14:28  来自大山深处的菜鸟  阅读(144)  评论(0编辑  收藏  举报