【HDU】5015 233 Matrix 矩阵快速幂

传送门:【HDU】5015 233 Matrix


题目分析:矩阵快速幂,构建一个如下的矩阵即可:


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 
#include 
#include 
#include 
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 ;
}




你可能感兴趣的:(矩阵快速幂)