wikioi Fibonacci数列(poj 3070)
2014-04-08 17:31
246 查看
题目描述 Description
定义:f0=f1=1, fn=fn-1+fn-2(n>=2)。{fi}称为Fibonacci数列。输入n,求fn mod q。其中1<=q<=30000。
输入描述 Input Description
第一行一个数T(1<=T<=10000)。以下T行,每行两个数,n,q(n<=109, 1<=q<=30000)
输出描述 Output Description
文件包含T行,每行对应一个答案。
样例输入 Sample Input
36 2
7 3
7 11
样例输出 Sample Output
10
10
数据范围及提示 Data Size & Hint
1<=T<=10000n<=109, 1<=q<=30000
题解:
矩阵上的快速幂,经典例题。首先明确一个概念,对角矩阵是一个主对角线之外的元素皆为 0 的矩阵。对角线上的元素可以为
0 或其他值。
即形如这样的矩阵:
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 1 |
思路在poj 3070的题目中有提到,只是有点不好想到,如果理解了矩阵乘法的基本内容,应该不难理解。
代码如下:
#include<cstdio> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> using namespace std; int n,q,a[2][2]/*标准矩阵*/,b[2][2]/*对角矩阵,相当于数字1*/; void mul(int x[2][2],int y[2][2],int z[2][2]) { int t[2][2]; for(int i=0;i<2;i++) for(int j=0;j<2;j++) {t[i][j]=0; for(int k=0;k<2;k++) t[i][j]=(t[i][j]+x[i][k]*y[k][j])%q; } for(int i=0;i<2;i++) for(int j=0;j<2;j++) z[i][j]=t[i][j]; } int ksm(int cs)//和快速幂很想,只是乘法和取mod部分要单独写,要注意结果保存在哪里 { while(cs) {if(cs&1) mul(a,b,b); cs=cs>>1; mul(a,a,a); } printf("%d\n",b[0][0]); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) {a[0][0]=1; a[0][1]=1; a[1][0]=1; a[1][1]=0; b[0][0]=b[1][1]=1; b[1][0]=b[0][1]=0; int x; scanf("%d%d",&x,&q); ksm(x); } return 0; }
相关文章推荐
- POJ 3070 Fibonacci数列 矩阵乘法及乘幂求法
- 【算法学习】POJ3070——利用分治法来计算Fibonacci数列的值
- poj 3070 <矩阵快速幂【模板】求Fibonacci数列>
- POJ 3070 Fibonacci (矩阵快速幂 Fibonacci数列新求法)
- POJ-3070 Fibonacci(矩阵快速幂求Fibonacci数列)
- 矩阵快速幂POJ-3070
- POJ 3070 矩阵经典6 最基础的Fibonacci递推
- 斐波那契数(POJ 3070)
- poj 3070 Fibonacci 【矩阵快速幂 求第N个斐波那契数%1000】
- poj 3070 Fibonacci(矩阵快速幂)
- poj 3070 Fibonacci
- 【poj 3070】Fibonacci
- poj 3070 矩阵快速幂模板
- POJ 3070 Fibonacci(矩阵乘法logN)
- poj 3070 Fibonacci(矩阵优化递推入门)
- poj 3070 Fibonacci 矩阵快速幂
- poj 3070
- poj3070 Fibonacci 矩阵快速幂
- 【矩阵乘法】Fibonacci数列 WikiOI 1732/1250
- poj3070(利用矩阵快速幂加速递推式)