【矩阵乘法】【codevs 1250】Fibonacci数列
2015-06-03 21:36
399 查看
1250 Fibonacci数列
[code] 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond
题目描述 Description
定义:f0=f1=1, fn=fn-1+fn-2(n>=2)。{fi}称为Fibonacci数列。
输入n,求fn mod q。其中1<=q<=30000。
输入描述 Input Description
[code]第一行一个数T(1<=T<=10000)。 以下T行,每行两个数,n,q(n<=10^9, 1<=q<=30000)
输出描述 Output Description
[code]文件包含T行,每行对应一个答案。
样例输入 Sample Input
[code]3 6 2 7 3 7 11
样例输出 Sample Output
[code]1 0 10
数据范围及提示 Data Size & Hint
[code]1<=T<=10000 n<=10^9, 1<=q<=30000
题解:
因为n是10^9,所以不能用朴素的O(n)的地推来解决,我们需要具有更加优秀复杂度的算法——矩阵乘来帮助。
先简单介绍一下它:
矩阵乘是O(logn)的复杂度,针对的对象是一个n行m列和一个m行p列的矩阵。矩阵乘所得到的就是一个n行p列的矩阵,这个矩阵的第i行第j列是由一个矩阵的第i行的每一个数与另一个矩阵的第j列的对应数乘积的加和。一般的情况下,我们可以用快速幂来进行加速。
朴素的矩阵乘:
[code]for (int i=1; i<=n; i++) for (int j=1; j<=p; j++) for (int k=1; k<=m; k++) c[i][j]+=a[i][k]*b[k][j];
回归问题,我们需要求的是Fibonacci数列的第n项,可以建立两个矩阵:
然后让它们两个相乘,我们可以得到这样的矩阵:
于是我们可以发现,对于f
而言,它实际上可以由这样两个矩阵转移来,而对于B矩阵,它也是由上一层转移来的,所以对于f
来说,它可以这样得到:
于是可以应用快速幂加速下的矩阵乘来解决。(传参时各种奇怪问题希望大家小心一下。。。)
Code:
[code]#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int T,n,q,ans,a[2][2],b[2][2]; int in(){ int x=0; char ch=getchar(); while (ch<'0' || ch>'9') ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); return x; } void init(){ a[0][0]=a[0][1]=a[1][0]=1; a[1][1]=0; b[0][0]=b[0][1]=b[1][0]=1; b[1][1]=0; } void matrix(int x[2][2],int y[2][2]){ int c[2][2]={0}; for (int i=0; i<=1; i++) for (int j=0; j<=1; j++) for (int k=0; k<=1; k++) c[i][j]=(c[i][j]+x[i][k]*y[k][j])%q; for (int i=0; i<=1; i++) for (int j=0; j<=1; j++) y[i][j]=c[i][j]; } int main(){ T=in(); while (T--){ n=in(),q=in(); init(); if (n<=1){ printf("1\n"); continue; } int y=n-2; while (y){ if (y&1) matrix(a,b); y>>=1; matrix(a,a); } ans=(b[0][0]+b[0][1])%q; printf("%d\n",ans); } return 0; }
相关文章推荐
- linux入门基础——linux用户基础
- 树莓派(raspberry)使用经验————设置有线和无线ip
- BZOJ 1601: [Usaco2008 Oct]灌水( MST )
- 【BZOJ】【1863】【ZJOI2006】trouble 皇帝的烦恼
- linux僵尸进程
- 4-2
- UNIX网路编程(第三版) 关于源代码的使用问题
- TCP学习(一)版本
- [欧拉回路] hdu 3018 Ant Trip
- android开源项目---View篇
- WARNING: The host '$hostname' could not be looked up with resolveip.
- is not in the sudoers file 解决
- 第十三周项目3——立体类族共有的抽象类
- disruptor实操作手册(一)
- Python文档生成工具pydoc
- poj 2505 A multiplication game(博弈)
- Linux下构造函数string需要注意的问题
- C#匿名类型
- java 获取昨天日期
- XTU 1173 Five Tiger(简单模拟)