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

题目分析:[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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值