看到题之后发现存在递推关系,所以可以想到是矩阵快速幂
所以构建初始矩阵a
23 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0 0 0
然后构建变换矩阵b
10 0 0 0 0 0 0 0 0 0 0 1
10 1 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1
然后就是快速幂的模板了,注意可能超int
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 13
#define MOD 10000007
#define size 11
using namespace std;
typedef long long LL;
struct mat
{
LL a[MAX][MAX];
mat ( )
{
memset ( a , 0 , sizeof ( a ) );
}
};
void set ( mat& m )
{
for ( int i = 0 ; i <= size ; i++ )
m.a[i][i] = 1;
}
mat multi ( mat m1 , mat m2 )
{
mat ret;
for ( int i = 0 ; i <= size ; i++ )
for ( int j = 0 ; j <= size ; j++ )
if ( m1.a[i][j] )
for ( int k = 0 ; k <= size ;k++ )
ret.a[i][k] = (ret.a[i][k]+(m1.a[i][j]*m2.a[j][k])%MOD)%MOD;
return ret;
}
mat quickMulti ( mat m , LL n )
{
mat ret;
set ( ret );
while ( n )
{
if ( n&1 ) ret = multi ( m , ret );
m = multi ( m , m );
n>>=1;
}
return ret;
}
void print ( mat a )
{
for ( int i = 0 ; i <= 11 ; i++ )
{
for ( int j = 0 ; j <= 11 ; j++ )
printf ( "%lld " , a.a[i][j] );
puts ( "" );
}
puts ( "" );
}
int n,m;
int main ( )
{
while ( ~scanf ( "%d%d" , &n , &m ) )
{
mat a , b;
a.a[11][0] = 3;
a.a[0][0] = 23;
for ( int i = 1 ; i <= n ; i++ ) scanf ( "%lld" , &a.a[i][0] );
for ( int i = 0 ; i <= n ; i++ )
b.a[i][0] = 10, b.a[i][11] = 1;
for ( int i = 1 ; i <= n ; i++ )
for ( int j = 1 ; j <= i ; j++ )
b.a[i][j] = 1;
b.a[11][11] = 1;
b = quickMulti ( b , m );
a = multi ( b , a );
printf ( "%lld\n" , a.a[n][0] );
}
}