233 Matrix HDU - 5015

原题链接

考察:矩阵快速幂

思路:

        题目的递推式是找不到关系矩阵的,由此必须换一个思路.由题目的数据范围发现n小m大,可以考虑由第i列推到第i+1列,我们要由一个1x(n+2)的矩阵*(n+2)x(n+2)的矩阵 = 新的1xn+2的矩阵.从常数项先考虑,我们要从233->2333. 显然 2333 = 233*10+3.考虑构造10和 3,再将题目给定的数据放入剩下的行中,可以由题目给定的公式推出下一列.

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 using namespace std;
 5 typedef long long LL;
 6 const int Mod = 10000007,N = 15;
 7 int n,m,f[N],a[N][N];
 8 void inits()
 9 {
10     f[0] = 23; f[n+1] = 3;
11     for(int i=1;i<=n;i++) scanf("%d",&f[i]);
12     for(int i=1;i<=n;i++)
13         for(int j=1;j<=n;j++)
14                if(i<=j) a[i][j] = 1;
15                else a[i][j] = 0;
16     for(int i=0;i<n+2;i++) a[0][i] = 10,a[n+1][i] = 1;
17     a[0][n+1] = 0;
18 }
19 void mul(int f[],int a[][N])
20 {
21     int res[N];
22     memset(res,0,sizeof res);
23     for(int i=0;i<n+2;i++)
24       for(int j=0;j<n+2;j++)
25          res[i] = (res[i]+(LL)f[j]*a[j][i])%Mod;
26     memcpy(f,res,sizeof res);
27 }
28 void mulself(int a[][N])
29 {
30     int res[N][N];
31     memset(res,0,sizeof res);
32     for(int i=0;i<n+2;i++)
33       for(int j=0;j<n+2;j++)
34         for(int k=0;k<n+2;k++)
35           res[i][j] = (res[i][j]+(LL)a[i][k]*a[k][j])%Mod;
36     memcpy(a,res,sizeof res);
37 }
38 int main() 
39 {
40     while(scanf("%d%d",&n,&m)!=EOF)
41     {
42         memset(f,0,sizeof f);
43         memset(a,0,sizeof a);
44         inits();
45         while(m)
46         {
47             if(m&1) mul(f,a);
48             mulself(a);
49             m>>=1;
50         }
51         printf("%d\n",f[n]);
52     }
53     return 0;
54 }

 

posted @ 2021-03-02 15:45  acmloser  阅读(38)  评论(0编辑  收藏  举报