HDU4549_M斐波那契数列_斐波那契数列&费马小定理
来源:互联网 发布:小米手机一直2g网络 编辑:程序博客网 时间:2024/05/20 09:08
题意
M斐波那契数列F[n]是一种整数数列,它的定义如下:
F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )
现在给出a, b, n,你能求出F[n]的值吗?
思路
写出几项便发现,a 的指数是 fib[n - 1], b 的指数是 fib[n],实际上是求斐波那契数列+快速幂。
费马小定理
特别的,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 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;}
阅读全文
0 0
- HDU4549_M斐波那契数列_斐波那契数列&费马小定理
- 齐肯多夫定理--斐波那契数列
- 09_斐波那契数列
- 09_斐波那契数列
- 6_斐波那契数列
- M斐波那契数列 - HDU 4549 费马小定理
- 斐波那契数列数列计算
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 学习日志0725
- Angular入门之输入输出绑定
- 剑指Offer:用两个栈实现队列(一刷)
- vb.net 教程 12-1 WebBrowser 2
- 类和对象
- HDU4549_M斐波那契数列_斐波那契数列&费马小定理
- python2.7 安装scrapy后报错
- java 单例设计模式
- 栈和队列的练习
- mongodb-索引
- 通过后缀表达式模拟计算器
- Spring——AOP核心思想与实现
- BZOJ 3670: [Noi2014]动物园 KMP题解
- 6.2 APP的签名与打包