您的位置:首页 > 其它

HDU4549_M斐波那契数列_斐波那契数列&费马小定理

2017-07-25 22:25 288 查看

题意

M斐波那契数列F
是一种整数数列,它的定义如下:

F[0] = a

F[1] = b

F
= F[n-1] * F[n-2] ( n > 1 )

现在给出a, b, n,你能求出F
的值吗?

思路

写出几项便发现,a 的指数是 fib[n - 1], b 的指数是 fib
,实际上是求斐波那契数列+快速幂。

费马小定理

特别的,mod 是素数,故可以利用费马小定理。

a^(p-1)≡1(mod p)

特别注意!本题中应用费马小定理的指数是通过矩阵快速幂求得的。在快速幂中的mod 都得是 mod - 1!而不能在求出结果后搞一个 % (mod - 1)!这太傻了。是的,太傻了。

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=4549

AC代码

#include<cstdio>
#include<iostream>
#include<vector>

using namespace std;

typedef long long LL;
typedef vector<LL> vec;
typedef vector<vec> mat;

int mod = 1000000007;

int a, b, n;

mat mul(mat A, mat B)
{
mat C(A.size(), vec(B[0].size()));

for(int i= 0; i< A.size(); i++)
for(int k= 0; k< B.size(); k++)
for(int j= 0; j< B[0].size(); j++)
C[i][j] = (C[i][j] + A[i][k] * B[k][j] % mod) % mod;

return C;
}

mat pow(mat A, LL n)
{
mat B(A.size(), vec(A.size()));
for(int i= 0; i< A.size(); i++)
B[i][i] = 1;

while(n > 0)
{
if(n & 1) B = mul(B, A);
A = mul(A, A);
n >>= 1;
}

return B;
}

int main()
{
while(scanf("%d %d %d", &a, &b, &n) != EOF)
{
if(n == 0){
cout << a % mod << endl;
continue;
}

mod = 1000000006;//mod - 1

bcb0
mat A(2, vec(2));
A[0][0] = A[0][1] = A[1][0] = 1, A[1][1] = 0;
A = pow(A, n - 1);

mod ++;

mat t1 (1, vec(1));
t1[0][0] = a;
t1 = pow(t1, A[1][0]);

mat t2 (1, vec(1));
t2[0][0] = b;
t2 = pow(t2, A[0][0]);

cout << t1[0][0] * t2[0][0] % mod << endl;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: