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=4549AC代码
#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; }
相关文章推荐
- HDU4549 M斐波那契数列
- hdu4549 M斐波那契数列(矩阵快速幂)
- 解题报告:HDU4549 M斐波那契数列 数论三大基础(快速幂+矩阵快速幂+费马小定理)
- nyoj1000&&hdu4549 M斐波那契数列 递推公式+矩阵
- hdu4549 M斐波那契数列 【矩阵快速幂+快速幂+欧拉函数降次】
- HDU4549 M斐波那契数列【矩阵快速幂】
- hdu4549 M斐波那契数列 矩阵快速幂+快速幂
- hdu4549 M斐波那契数列 (矩阵快速幂+费马小定理)
- hdu4549---M斐波那契数列(矩阵+欧拉定理)
- hdu4549 斐波那契数列(乘法递推) + 欧拉定理 (快速幂,模幂)
- 输出斐波那契数列前n项,十个一行 ,行末不含空格
- C/C++经典程序训练2---斐波那契数列
- 剑指offer-斐波那契数列
- NUC1016 斐波那契数列【打表】
- 斐波那契数列的算法优化
- Java 兔子问题(斐波那契数列)扩展篇
- 斐波那契数列
- 面试题9. 斐波那契数列
- 斐波那契数列
- 使用黄金分割比值计算斐波那契数列