hdu 1588 Gauss Fibonacci(矩阵乘法,二分)

来源:互联网 发布:java数组转成字符串 编辑:程序博客网 时间:2024/05/01 01:38

题目分析:[f(n),f(n-1)]=[1,1;  1,0]^(n-1)*[f(1),f(0)];

A=[1,1;1,0];

求:{A^b*(A^0+A^k+A^[2*k]+A^[3*k],,,+A^[(n-1)*k])}*(A的逆矩阵).....

注意的地方:

     1.重载了*,+,注意优先级呀,不是自以为的*比+的优先级高,所以要加括号

     2. 注意乘上A的逆矩阵

     3.注意for(int i=1;i<=n;p++)的低级的错误

     4.求A^k+A^[2*k]+A^[3*k],,,+A^[(n-1)*k]时,用fun(ma,t)是错的,所以改为,fun(ma^k,t),


AC 代码:

#include<iostream>#include<cstdio>#include<memory.h>using namespace std;struct node {__int64 matrix[3][3];}ma,e;__int64 M,k;node operator +(node x,node y){node temp;memset(temp.matrix,0,sizeof(temp.matrix));for(int i=1;i<=2;i++)for(int j=1;j<=2;j++){temp.matrix[i][j]=(x.matrix[i][j]+y.matrix[i][j])%M;}return temp;}node operator *(node x,node y){node temp;for(int i=1;i<=2;i++)for(int j=1;j<=2;j++)    {temp.matrix[i][j]=0;for(int p=1;p<=2;p++)temp.matrix[i][j]+=x.matrix[i][p]*y.matrix[p][j];temp.matrix[i][j]%=M;}return temp;}node operator ^(node a,__int64 t)//a^t;{    if(t==0)return e;node ans=e,p=a;while(t){if(t%2==1){ans=ans*p;}t=t/2;p=p*p;}return ans;}/*错在没注意优先级node fun(node a,__int64 t)//a^k+a^2k+a^3k+,,,+a^(t*k){//printf("t=%d   ",t);if(t==0)return  e;if(t==1)return a^k;if(t%2==1){return  fun(a,t-1)+a^(t*k);//(e+a^(k*(t/2)))*fun(a,(t/2))+a^(t*k);}elsereturn (e+a^(k*(t/2)))*fun(a,(t/2));}*/node fun(node a,__int64 t)//a^1+a^2+a^3+...+a^t{if(t==0)return  e;if(t==1)return a;if(t%2==1){return  fun(a,t-1)+(a^(t));//注意打括号,,,}elsereturn (e+(a^(t/2)))*fun(a,(t/2));//(e+a^(t/2))*fun(a,(t/2));....错在没注意优先级!!!!}int main(){__int64 b,n;memset(e.matrix,0,sizeof(e.matrix));e.matrix[1][1]=e.matrix[2][2]=1;ma.matrix[1][1]=ma.matrix[1][2]=ma.matrix[2][1]=1;ma.matrix[2][2]=0;    node t1;t1.matrix[1][2]=t1.matrix[2][1]=1;t1.matrix[1][1]=0;t1.matrix[2][2]=-1;while(scanf("%I64d %I64d %I64d %I64d",&k,&b,&n,&M)!=EOF){node a;        node temp=((ma^0)+(ma^2)+(ma^4)+(ma^6))*(ma^b)*t1;if(n>=2){a=(fun(ma^k,n-1)+e)*(ma^b)*t1;}else   a=e*(ma^b);__int64 ans=a.matrix[1][1]%M;printf("%I64d\n",ans);}system("pause");return 0;}


有错误的代码,,,

代码:

#include<iostream>#include<cstdio>#include<memory.h>using namespace std;struct node {__int64 matrix[3][3];}ma,e;__int64 M,k;node operator +(node x,node y){node temp;memset(temp.matrix,0,sizeof(temp.matrix));for(int i=1;i<=2;i++)for(int j=1;j<=2;j++){temp.matrix[i][j]=(x.matrix[i][j]+y.matrix[i][j])%M;}return temp;}node operator *(node x,node y){node temp;for(int i=1;i<=2;i++)for(int j=1;j<=2;j++)    {temp.matrix[i][j]=0;for(int p=1;p<=2;p++)temp.matrix[i][j]+=x.matrix[i][p]*y.matrix[p][j];temp.matrix[i][j]%=M;}return temp;}node operator ^(node a,__int64 t)//a^t;{    if(t==0)return e;node ans=e,p=a;while(t){if(t%2==1){ans=ans*p;}t=t/2;p=p*p;}return ans;}node fun(node a,__int64 t)//a^k+a^2k+a^3k+,,,+a^(t*k){//printf("t=%d   ",t);if(t==0)return  e;if(t==1)return a^k;if(t%2==1){return  fun(a,t-1)+a^(t*k);//(e+a^(k*(t/2)))*fun(a,(t/2))+a^(t*k);}elsereturn (e+a^(k*(t/2)))*fun(a,(t/2));}int main(){__int64 b,n;memset(e.matrix,0,sizeof(e.matrix));e.matrix[1][1]=e.matrix[2][2]=1;ma.matrix[1][1]=ma.matrix[1][2]=ma.matrix[2][1]=1;ma.matrix[2][2]=0;/*for(int i=1;i<=2;i++){for(int j=1;j<=2;j++)printf("%I64d  ",e.matrix[i][j]);printf("\n");}*/while(scanf("%I64d %I64d %I64d %I64d",&k,&b,&n,&M)!=EOF){node a;if(n>=2)   a=(fun(ma,n-1)+e)*(ma^b);else   a=e*(ma^b);for(int i=1;i<=2;i++){for(int j=1;j<=2;j++)printf("%I64d    ",a.matrix[i][j]);printf("\n");}__int64 ans=a.matrix[1][1]%M;printf("%I64d\n",ans);}system("pause");return 0;}