M斐波那契数列
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 4 Accepted Submission(s) : 1
Problem 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]的值吗?
Input
输入包含多组测试数据; 每组数据占一行,包含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
Source
2013金山西山居创意游戏程序挑战赛——初赛(2)
指数呈斐波那契规律,注意指数可能很大,需要使用费马小定理
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
#define ll long long int
const ll p = 1e9 + 7;
const int maxn = 2;
struct node {
ll a[2][2];
void Clear() {
memset(a, 0, sizeof a);
}
};
node mul(node a, node b)
{
node c; int i, j,k;
for (i = 0; i<maxn; i++)
{
for (j = 0; j<maxn; j++)
{
c.a[i][j] = 0;
for (k = 0; k<maxn; k++)
c.a[i][j] += (a.a[i][k] * b.a[k][j]) % (p - 1);
c.a[i][j] %= (p - 1);
}
}
return c;
}
node get_f(ll x)
{
node f;
f.Clear();
f.a[0][0] = 1;
f.a[1][1] = 1;
node tmp;
tmp.Clear(); tmp.a[1][1] = 1; tmp.a[0][1] = 1; tmp.a[1][0] = 1;
while (x) {
if (x % 2 == 1) {
f = mul(f, tmp);
}
tmp = mul(tmp, tmp);
x >>= 1;
}
return f;
}
ll qkm(ll a, ll b) {
if (b == 1) return a;
ll ans = 1;
a %= p;
while (b)
{
if (b % 2)
(ans *= a) %= p;
(a = a * a) %= p;
b >>= 1;
}
return ans;
}
int main()
{
ll a, b, n;
while (scanf("%lld%lld%lld", &a, &b, &n) != EOF)
{
/*if (n == 0) { cout << a << endl; continue; }
if (n == 1) { cout << b << endl; continue; }
if (n == 2) { cout << a * b%p << endl; continue; }
node x = get_f(n - 2);
ll z = x.a[0][0];
x = get_f(n - 3);
ll y = x.a[0][0];
a = qkm(a, y); a %= (p-1);
b = qkm(b, z); b %= (p-1);
printf("%lld\n", a*b%p);*/
node x = get_f(n);
ll ans = (qkm(a, x.a[0][0])*qkm(b, x.a[1][0])) % p;
cout << ans << endl;
}
return 0;
}