hdu4549 矩阵快速幂 + 欧拉降幂
Appoint description:
Description
M斐波那契数列F[n]是一种整数数列,它的定义如下:
F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )
现在给出a, b, n,你能求出F[n]的值吗?
F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )
现在给出a, b, n,你能求出F[n]的值吗?
Input
输入包含多组测试数据;
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )
Output
对每组测试数据请输出一个整数F[n],由于F[n]可能很大,你只需输出F[n]对1000000007取模后的值即可,每组数据输出一行。
Sample Input
0 1 0
6 10 2
Sample Output
0
60
列出数列的前几项可以观察得到,每一项的a,b的值满足f[i] = f[i-1] + f[i-2],所以能够用矩阵构造。 但是我们的答案最后要取mod,矩阵里的值可能也会超过long long,
所以也需要降幂,此时可以用欧拉降幂,如果有公式a^x (mod m),并且gcd(x,m)==1,即x和m互质,那么a^x = a^(x % Eular(m));由于m是质数,所以Eular(m) = m - 1;
最后再快速幂、相乘(要取模)即可;
#include<map> #include<set> #include<string> #include<queue> #include<stack> #include<cmath> #include<vector> #include<cstdio> #include<time.h> #include<cstring> #include<iostream> #include<algorithm> #define INF 1000000001 #define ll long long #define MOD 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int MAXN = 100010; struct Mat { ll a[2][2]; }; ll fa,fb,n; Mat operator *(Mat a,Mat b) { Mat c; memset(c.a,0,sizeof(c.a)); for(int i = 0; i < 2; i++){ for(int j = 0; j < 2; j++){ for(int k = 0; k < 2;k++){ c.a[i][j] += (a.a[i][k] * b.a[k][j])%(MOD-1); } } } return c; } Mat power(Mat b,ll n) { Mat c; c.a[0][0] = c.a[1][1] = 1; c.a[0][1] = c.a[1][0] = 0; while(n){ if(n & 1){ c = c * b; } b = b * b; n >>= 1; } return c; } ll mod_pow(ll x,ll n) { ll res = 1; while(n){ if(n & 1) res = res * x % MOD; x = x * x % MOD; n >>= 1; } return res; } ll mod_mul(ll a,ll b) { ll res = 0; while(b){ if(b & 1){ res = (res + a) % MOD; } b >>= 1; a = (a + a) % MOD; } return res; } int main() { while(~scanf("%lld%lld%lld",&fa,&fb,&n)){ if(fa == 0 || fb == 0){ cout<<0<<endl; continue; } if(n == 0){ cout<<fa%MOD<<endl; continue; } else if(n == 1){ cout<<fb%MOD<<endl; continue; } Mat a; a.a[0][0] = 0; a.a[0][1] = a.a[1][0] = a.a[1][1] = 1; a = power(a,n-2); ll num1 = (a.a[0][0] + a.a[0][1])%(MOD-1); ll num2 = (a.a[1][0] + a.a[1][1])%(MOD-1); ll ans1 = mod_pow(fa,num1); ll ans2 = mod_pow(fb,num2); ll ans = mod_mul(ans1,ans2); printf("%lld\n",ans); } return 0; }