HDU 4549 M斐波那契数列 ( 矩阵快速幂 + 费马小定理 )
题意:中文题,不解释
分析:最好的分析就是先推一推前几项,看看有什么规律
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef __int64 LL; #define CLR( a, b ) memset( a, b, sizeof(a) ) #define MOD 1000000007 struct Mat { LL mat[2][2]; Mat() { CLR( mat, 0 ); } void init() { for( int i = 0; i < 2; ++i ) for( int j = 0; j < 2; ++j ) mat[i][j] = ( i == j ); } void zero() { CLR( mat, 0 ); } Mat operator * ( const Mat &b ) const { Mat c; c.zero(); for( int k = 0; k < 2; ++k ) for( int i = 0; i < 2; ++i ) if( mat[i][k] ) for( int j = 0; j < 2; ++j ) c.mat[i][j] = ( c.mat[i][j] + mat[i][k] * b.mat[k][j] ) % ( MOD - 1 ); return c; } }; Mat Mat_mod( Mat a, LL b ) { Mat c; c.init(); while( b ) { if( b & 1 ) c = c * a; a = a * a; b >>= 1; } return c; } LL fast_mod( LL a, LL b ) { LL ans = 1; while( b ) { if( b & 1 ) ans = ans * a % MOD; a = a * a % MOD; b >>= 1; } return ans; } void Orz() { Mat c; c.mat[0][1] = c.mat[1][0] = c.mat[1][1] = 1; LL a, b, n; while( ~scanf( "%I64d %I64d %I64d",&a, &b, &n ) ) { if( n == 0 ) printf( "%I64d\n", a % MOD ); else if( n == 1 ) printf( "%I64d\n", b % MOD ); else if( n == 2 ) printf( "%I64d\n", a * b % MOD ); else { //0 1 1 2 3 5 8 13 Mat t = Mat_mod( c, n - 3 ); LL n1 = ( t.mat[1][0] + t.mat[1][1] ) % ( MOD - 1 ); t = t * c; LL n2 = ( t.mat[1][0] + t.mat[1][1] ) % ( MOD - 1 ); LL ans = fast_mod( a, n1 ) * fast_mod( b, n2 ) % MOD; printf( "%I64d\n", ans ); } } } int main() { Orz(); return 0; }
代码君
时间: 2024-12-20 12:17:37