您的位置:首页 > 其它

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

2012-09-13 19:43 351 查看
题目分析:[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);
}
else
return (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));//注意打括号,,,
}
else
return (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);
}
else
return (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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: