题目分析:矩阵快速幂,构建一个如下的矩阵即可:
n+2行的矩阵
-- -- -- --
| 1 1 1 1 1 1 1 0 | | a1 |
| 0 1 1 1 1 1 1 0 | | a2 |
| 0 0 1 1 1 1 1 0 | | a3 |
| 0 0 0 1 1 1 1 0 | | a4 |
| 0 0 0 0 1 1 1 0 | * | a5 |
| 0 0 0 0 0 1 1 0 | | an |
| - - - - - - - - - - - | | |
| 0 0 0 0 0 0 10 1 | | 233|
| 0 0 0 0 0 0 0 1 | | 3 |
-- -- -- --
代码如下:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
typedef long long LL ;
#define REP( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define REV( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof a )
#define CPY( a , x ) memcpy ( a , x , sizeof a )
#define ls ( o << 1 )
#define rs ( o << 1 | 1 )
#define lson ls , l , m
#define rson rs , m + 1 , r
#define root 1 , 1 , n
#define rt o , l , r
#define mid ( ( l + r ) >> 1 )
const int MAXN = 12 ;
const int mod = 10000007 ;
struct Matrix {
LL mat[MAXN][MAXN] ;
int n ;
Matrix ( int n = 0 ) : n ( n ) {}
void clear () {
CLR ( mat , 0 ) ;
}
void init () {
REP ( i , 0 , n ) REP ( j , 0 , n ) mat[i][j] = i == j ;
}
Matrix operator * ( const Matrix& a ) const {
Matrix c ( n ) ;
c.clear () ;
REP ( i , 0 , n ) REP ( j , 0 , n ) REP ( k , 0 , n ) c.mat[i][j] = ( c.mat[i][j] + mat[i][k] * a.mat[k][j] ) % mod ;
return c ;
}
} ;
int num[12] , n , m ;
Matrix pow ( const Matrix& A , int n ) {
Matrix res ( A.n ) ;
res.init () ;
Matrix tmp = A ;
while ( n ) {
if ( n & 1 ) res = res * tmp ;
tmp = tmp * tmp ;
n >>= 1 ;
}
return res ;
}
void solve () {
Matrix A ( n + 2 ) ;
A.clear () ;
REV ( i , n - 1 , 0 ) scanf ( "%d" , &num[i] ) ;
num[n] = 233 ;
num[n + 1] = 3 ;
n += 2 ;
REP ( i , 0 , n ) REP ( j , i , n ) A.mat[i][j] = 1 ;
REP ( i , 0 , n - 2 ) A.mat[i][n - 1] = 0 ;
A.mat[n - 2][n - 2] = 10 ;
Matrix res = pow ( A , m ) ;
int ans = 0 ;
REP ( i , 0 , n ) ans = ( ans + res.mat[0][i] * num[i] ) % mod ;
printf ( "%d\n" , ans ) ;
}
int main () {
while ( ~scanf ( "%d%d" , &n , &m ) ) solve () ;
return 0 ;
}