与hdu 3221类似......不想多说
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define MOD 1000000007
using namespace std;
typedef long long LL;
struct mat
{
LL m[3][3];
mat ( )
{
memset ( m , 0 , sizeof ( m ) );
}
};
mat multi ( mat a , mat b , LL mod )
{
mat c;
for ( LL i = 1 ; i < 3 ; i++ )
for ( LL j = 1 ; j < 3 ; j++ )
if ( a.m[i][j] )
for ( LL k = 1 ; k < 3 ; k++ )
c.m[i][k] = (c.m[i][k] + a.m[i][j]*b.m[j][k]%mod )%mod;
return c;
}
mat quickMulti ( mat a , LL n , LL mod )
{
mat ans;
for ( int i = 1 ; i < 3 ; i++ ) ans.m[i][i] = 1;
while ( n )
{
if ( n&1 ) ans = multi ( ans , a , mod );
a = multi ( a , a , mod );
n >>= 1;
}
return ans;
}
LL pow ( LL num , LL n )
{
LL ans = 1;
while ( n )
{
if ( n&1 ) ans = ans * num % MOD;
num = num*num%MOD;
n >>= 1;
}
return ans;
}
LL euler ( LL x )
{
LL res = x;
for ( int i = 2 ; i*i<=x ; i++ )
{
if ( x%i ) continue;
res -= res/i;
while ( x%i==0 ) x /= 1;
}
if ( x > 1 ) res -= res/x;
return res;
}
LL index ( LL n , LL mod )
{
LL a = 1 , b = 0 ,temp , i ;
for ( i = 1 ; i <= n ; i++ )
{
temp = a + b;
b = a;
a = temp;
if ( a >= mod ) break;
}
if ( i > n ) return a;
mat ma ,mb;
ma.m[1][1] = mb.m[1][1] = mb.m[2][1] = mb.m[1][2]=1;
mb = quickMulti ( mb , n , mod );
ma = multi ( ma , mb , mod );
return ma.m[1][1]%mod + mod;
}
int main ( )
{
LL phi = euler ( MOD );
LL a,b,n;
while ( ~scanf ( "%lld%lld%lld" , &a , &b , &n ) )
{
if ( n == 0 )
{
printf ( "%lld\n" , a%MOD );
continue;
}
if ( n == 1 )
{
printf ( "%lld\n" , b%MOD );
continue;
}
if ( a == 0 || b == 0 )
{
printf ( "0\n" );
continue;
}
LL ans = pow ( a , index(n-2 , phi ))*pow( b , index ( n-1 , phi ))%MOD;
printf ( "%lld\n" , ans );
}
}
本文介绍了一种使用矩阵快速幂求解斐波那契数列的方法,并结合欧拉函数进行模运算优化。通过定义特定矩阵并利用快速幂算法加速计算过程,同时介绍了如何求解模意义下的逆元。
6892

被折叠的 条评论
为什么被折叠?



