//对于一个n*(m+1)的矩阵n<=10 ,m<=1e9 //a[0][0] = 0 , a[0][1] = 233 , a[0][2] = 2333 , a[0][3] = 23333... //给出a[1][0] ... a[n][0] //其他的a[i][j] = a[i-1][j] + a[i][j-1] //可以推到a[n][m] = a[n][m-1] + a[n-1][m-1] + a[n-2][m-1] + ... + a[1][m-1] + a[0][m] //a[0][m] = a[0][m-1]*10 + 3 //可以通过这个递推式构造矩阵 // a[n][m] 1 1 1 ... 1 0 a[n][m-1] // a[n-1][m] 0 1 1 ... 1 0 a[n-1][m-1] // a[n-2][m] 0 0 1 ... 1 0 a[n-2][m-1] // ... ... ... // a[0][m+1] 0 0 0 ... 10 3 a[0][m-1] // 1 0 0 0 ... 0 1 1 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn = 15 ; typedef long long ll ; const ll mod = 10000007 ; int n , m ; ll a[maxn] ; struct node { ll p[maxn][maxn] ; }; node mul(node a , node b) { node c ; for(int i = 1;i <= n;i++) for(int j = 1;j <= n;j++) { c.p[i][j] = 0 ; for(int k = 1;k <= n;k++) c.p[i][j] = (c.p[i][j] + a.p[i][k]*b.p[k][j])%mod ; } return c ; } node pow(node a , int k) { node c ; memset(c.p , 0 , sizeof(c.p)) ; for(int i = 1;i <= n;i++) c.p[i][i] = 1 ; while(k) { if(k&1)c = mul(c , a) ; a = mul(a , a) ; k >>= 1 ; } return c ; } int main() { //freopen("in.txt" , "r" , stdin) ; while(~scanf("%d%d" , &n , &m)) { node b ; memset(b.p , 0 , sizeof(b)) ; for(int i = 1;i <= n;i++) scanf("%lld" , &b.p[n - i + 1][1]) ; b.p[n+1][1] = 233 ; b.p[n+2][1] = 1 ; node a ; memset(a.p , 0 , sizeof(a.p)) ; for(int i = 1;i <= n;i++) for(int j = i;j <= n + 1;j++) a.p[i][j] = 1 ; a.p[n+1][n+1] = 10 ; a.p[n+1][n+2] = 3 ; a.p[n+2][n+2] = 1 ; n += 2; a = pow(a , m) ; node c = mul(a , b) ; cout<<c.p[1][1]<<endl; } }