【NOIP2016提高A组模拟7.15】斐波那契数列(矩阵乘法)
2017-09-18 19:50
381 查看
题目
数据
小结
30%做法不知道怎么做出来的~暴力都能60吧。60%暴力咯~
100%
然后就是比较恶心的一个东西:叫做“矩阵乘法”。
这东西大家应该不用理解太久,连我这个蒟蒻都只是理解了半个小时~
不讲废话:
我们的斐波那契数列是这样的:
0 1 1 2 3 5 8 13…….
我们一个矩阵,只有两个数,就是我们当前的这个以及前一个,这样就可以推出下一个了。
推一推:
发现,答案的第一位就是原始数的第二位,那么原始数的第一位对答案的第一位是没有贡献的,所以:
我们考虑后面,第二位是前面两位之和,那么就两个都有贡献咯~
这样这个矩阵就推出来啦,我们就可以用快速幂的思想去做,其实就是乘这个矩阵n-1次。
#include<cstdio> #include<iostream> using namespace std; long long n,m; long long a[3],b[3,3],c[3],d[3,3]; void ksm(long long n,long long p) { int i,j,k; while(n) { if(n&1) { c[1]=0;c[2]=0; for (i=1;i<=2;++i) for (j=1;j<=2;++j) (c[i]+=a[j]*b[j,i])%=p; a[1]=c[1];a[2]=c[2]; } n>>=1; d[1,1]=0;d[1,2]=0; d[2,1]=0;d[2,2]=0; for (i=1;i<=2;++i) for (j=1;j<=2;++j) for (k=1;k<=2;++k) (d[i,j]+=b[i,k]*b[k,j])%=p; b[1,1]=d[1,1];b[1,2]=d[1,2]; b[2,1]=d[2,1];b[2,2]=d[2,2]; } } int main() { scanf("%lld%lld",&n,&m); b[1,1]=0; b[1,2]=1; b[2,1]=1; b[2,2]=1; a[1]=1; a[2]=1; ksm(n-1,m); printf("%lld\n",a[2]); }
相关文章推荐
- 【NOIP2016提高A组模拟9.24】天使的分裂 (矩阵乘法)
- 【NOIP2016提高A组模拟7.15】计数
- 【NOIP2016提高A组模拟7.15】立方体
- 【NOIP2016提高A组模拟7.15】颜料大乱斗 题解+代码
- JZOJ 4603 颜料大乱斗【NOIP2016提高A组模拟7.15】
- 【NOIP2016提高A组模拟7.15】颜料大乱斗
- 颜料大乱斗【NOIP2016提高A组模拟7.15】
- 【NOIP2016提高A组模拟9.21】矩阵
- 矩阵【NOIP2016提高A组模拟9.21】
- 就是乘法【NOIP2016提高A组模拟9.24】
- JZOJ 4629 修路【NOIP2016提高A组模拟7.15】
- [JZSC2016] 【NOIP2016提高A组模拟7.15】总结
- [jzoj4603]【NOIP2016提高A组模拟7.15】颜料大乱斗
- 【JZOJ5335】【NOIP2017提高组模拟】早苗(DP、矩阵乘法)
- 【JZOJ4791】【NOIP2016提高A组模拟9.21】矩阵
- 【NOIP2016提高A组模拟7.15】修路 题解+代码
- 【NOIP2016提高A组模拟9.24】就是乘法
- 【NOIP2016提高A组模拟7.15】计数 题解+代码
- JZOJ 4630 计数【NOIP2016提高A组模拟7.15】
- 计数【NOIP2016提高A组模拟7.15】