杭电2855 Fibonacci Check-up
2012-02-15 08:45 javaspring 阅读(165) 评论(0) 编辑 收藏 举报是一道数论方面的题,融合了矩阵二分幂和多项式定理以及斐波那契数列的一道题。先用公式可以推出来,之后用矩阵二分幂就可以了。
关于矩阵二分幂,实际上就是矩阵的乘法,由于矩阵满足结合律,故可以用平方来计算,就达到了log(n)的复杂度,由于n可能为奇数,可能为偶数,所以当n为奇数时,还需要乘以初始矩阵。
ac代码:
#include <iostream> #include <cmath> #include <stdio.h> using namespace std; int m; int matrix[2][2];//存储结果的矩阵 void cheng(int n){ int x,y,z,w; //矩阵乘法运算 x=((matrix[0][0]%m)*(matrix[0][0]%m))%m+((matrix[0][1]%m)*(matrix[1][0]%m))%m; y=((matrix[0][0]%m)*(matrix[0][1]%m))+((matrix[0][1]%m)*(matrix[1][1]%m)); z=((matrix[1][0]%m)*(matrix[0][0]%m))+((matrix[1][1]%m)*(matrix[1][0]%m)); w=((matrix[1][0]%m)*(matrix[0][1]%m))+((matrix[1][1]%m)*(matrix[1][1]%m)); matrix[0][0]=x;matrix[0][1]=y;matrix[1][0]=z;matrix[1][1]=w; if(n%2){//乘初始矩阵 x=(matrix[0][0]%m+matrix[0][1]%m)%m;y=matrix[0][0]%m; z=(matrix[1][0]%m+matrix[1][1]%m)%m;w=matrix[1][0]%m; matrix[0][0]=x;matrix[0][1]=y;matrix[1][0]=z;matrix[1][1]=w; } //取余运算 matrix[0][0]%=m; matrix[0][1]%=m; matrix[1][0]%=m; matrix[1][1]%=m; } void dfs(int n){ if(n==0){ matrix[0][1]=0;return; } else if(n==1){ matrix[0][1]=1;return; } dfs(n/2); if(n%2){//根据n的奇偶性判断是否需要乘初始矩阵 cheng(1); } else cheng(2); } int main(){ //freopen("1.txt","r",stdin); int ncase;//数据组数 scanf("%d",&ncase); while(ncase--){ int n; scanf("%d%d",&n,&m); matrix[0][0]=1;matrix[0][1]=1; matrix[1][0]=1;matrix[1][1]=0; n=n*2; dfs(n);//求结果 printf("%d\n",matrix[0][1]%m); } return 0; }