传送门:【HDU】1588 Gauss Fibonacci
题目分析:矩阵快速幂妥妥的。
首先我们设斐波那契第N项为f( n ),则:
| 1 1 |
令A = | |,则f( n ) 等于( A^n )的右上角那项。
| 1 0 |
然后f( g( i ) ) = f ( k * i + b ) = ( A ^ ( k * i ) ) * ( A ^ b )
易得res = sum{f( g( i ) ),0 <= i < n } = ( A ^ b ) * ( E(单位矩阵) + A^k + A^( 2k ) + A^( 3k ) + …… + A^( (n - 1)k )。
| E 0 |
令C = A^k , B = | |,则B ^ ( n - 1 )的左下角即D = A^k + A^( 2k ) + A^( 3k ) + …… + A^( ( n - 1 )k )
| C C |
则res = ( A ^ b ) * ( D + E )。
矩阵res的右上角即答案。
代码如下:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; typedef long long LL ; #define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next ) #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 F( i ) ( ( ( i ) - 1 ) % n + 1 ) const int MAXN = 4 ; int mod ; struct Matrix { LL mat[MAXN][MAXN] ; int n ; Matrix () {} Matrix ( int n ) : 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 ; } Matrix operator + ( const Matrix& a ) const { Matrix c ( n ) ; rep ( i , 0 , n ) rep ( j , 0 , n ) { c.mat[i][j] = mat[i][j] + a.mat[i][j] ; if ( c.mat[i][j] >= mod ) c.mat[i][j] -= mod ; } return c ; } Matrix operator *= ( const Matrix& a ) const { return ( *this ) * a ; } Matrix operator += ( const Matrix& a ) const { return ( *this ) + a ; } } ; int k , b , n ; Matrix pow ( Matrix A , int b ) { Matrix res ( A.n ) ; res.init () ; Matrix tmp = A ; while ( b ) { if ( b & 1 ) res = res * tmp ; tmp = tmp * tmp ; b >>= 1 ; } return res ; } void solve () { Matrix A ( 2 ) ;//Fibonacci Matrix B ( 4 ) ;//A^k矩阵的构造矩阵 Matrix C ( 2 ) ;//求A^k Matrix D ( 2 ) ;//B矩阵的k次方和 Matrix E ( 2 ) ;//单位矩阵 E.init () ; A.mat[0][0] = 1 ; A.mat[0][1] = 1 ; A.mat[1][0] = 1 ; A.mat[1][1] = 0 ; C = pow ( A , k ) ; B.mat[0][0] = 1 ; B.mat[0][1] = 0 ; B.mat[0][2] = 0 ; B.mat[0][3] = 0 ; B.mat[1][0] = 0 ; B.mat[1][1] = 1 ; B.mat[1][2] = 0 ; B.mat[1][3] = 0 ; B.mat[2][0] = C.mat[0][0] ; B.mat[2][1] = C.mat[0][1] ; B.mat[2][2] = C.mat[0][0] ; B.mat[2][3] = C.mat[0][1] ; B.mat[3][0] = C.mat[1][0] ; B.mat[3][1] = C.mat[1][1] ; B.mat[3][2] = C.mat[1][0] ; B.mat[3][3] = C.mat[1][1] ; B = pow ( B , n - 1 ) ; D.mat[0][0] = B.mat[2][0] ; D.mat[0][1] = B.mat[2][1] ; D.mat[1][0] = B.mat[3][0] ; D.mat[1][1] = B.mat[3][1] ; Matrix res = pow ( A , b ) * ( D + E ) ; printf ( "%I64d\n" , res.mat[0][1] ) ; } int main () { while ( ~scanf ( "%d%d%d%d" , &k , &b , &n , &mod ) ) solve () ; return 0 ; }