2017.3.25 矩阵快速幂 求斐波那契数列第n项

       对于矩阵快速幂只要知道矩阵取模、乘法原理就完全可以手推

        口诀:行 列         被计算的行列的交点是结果对应的位置:

     剩下的就是推矩阵:

其实根据矩阵的方程意义就很好推了:

  2017.3.25 矩阵快速幂 求斐波那契数列第n项_第1张图片


码:

#include
#include
using namespace std;
#define ll long long
struct juzhen
{
	ll hang,lie;
	ll jz[3][3];
	juzhen()
	{
		
		jz[0][0]=jz[0][1]=jz[1][1]=jz[1][2]=jz[2][1]=jz[1][0]=jz[2][2]=0;
		hang=0,lie=0;	
	}
};
ll i,j,k;
int n,p=999;
juzhen jzcheng(juzhen a,juzhen b)
{   
	juzhen ans;
	ans.hang=a.hang;
	ans.lie=b.lie;
	
	for(int i=1;i<=ans.hang;i++)
	{
		for(int j=1;j<=ans.lie;j++)
		{
		for(int k=1;k<=ans.lie;k++)
		{
			ans.jz[i][j]=(ans.jz[i][j]+(a.jz[i][k]*b.jz[k][j])%p)%p;
		}		
	    }		
	}	
	return ans;
}
void cheng(juzhen a,int b)
{
	for(int i=1;i<=a.hang;i++)
	for(int j=1;j<=a.lie;j++)
	{
		a.jz[i][j]=(a.jz[i][j]*b)%p;		
	}
}

juzhen jzkuai(juzhen a,int b)
{
	juzhen ans;
	ans.hang=a.hang;
	ans.lie=a.lie;
	ans.jz[2][2]=1;
	ans.jz[1][1]=1;
	ans.jz[1][2]=ans.jz[2][1]=0;
	
	while(b)
	{   
		if(b&1)
		{
	     	ans=jzcheng(ans,a);   			
		}		
		b/=2; a=jzcheng(a,a);
			
	}
	
	return ans;
}




int main()
{
	
	scanf("%d%d",&n,&p);
	
	juzhen s1,s2;
	s1.hang=2;
	s1.lie=1;
	s1.jz[1][1]=1;
	
	s1.jz[2][1]=0;
	n--;
	
	s2.hang=2;
	s2.lie=2;
	s2.jz[1][1]=1;
	s2.jz[1][2]=1;
	s2.jz[2][1]=1;
	s2.jz[2][2]=0;
	
	juzhen daan=jzcheng(jzkuai(s2,n),s1);

	
	cout<


       


你可能感兴趣的:(题目)