斐波那契公约数,洛谷之提高历练地,数论(3-5)

正题

      第五题:斐波那契公约数

       我们回想一下斐波那契的数列,关于他的求法和性质,可以知道,它是可以用矩阵乘法来求的。

      因为f[i]=f[i-1]+f[i-2].所以我们就可以构造出这样一个矩阵。


没错。因为矩乘就是这样,第一个方阵的i行乘上第二个方阵的j列,得出结果方阵的i行j列。

代码<简短但是很简单>

#include
#include
#include

int n,m;
long long s[2][2]={0,1,1,1};
long long a[2]={1,1};
long long tot[2][2]={1,0,0,1};
long long now[2][2];
const long long mod=100000000;

int gcd(int x,int y)
{
	if(x%y==0) return y;
	return gcd(y,x%y);
}

int main()
{
	scanf("%d %d",&n,&m);
	if(n0)
	{
		if(g%2==1)
		{
			for(int i=0;i<2;i++)
				for(int j=0;j<2;j++)
					now[i][j]=tot[i][j];
			tot[0][0]=now[0][0]*s[0][0]+now[0][1]*s[1][0];
			tot[0][1]=now[0][0]*s[0][1]+now[0][1]*s[1][1];
			tot[1][0]=now[1][0]*s[0][0]+now[1][1]*s[1][0];
			tot[1][1]=now[1][0]*s[0][1]+now[1][1]*s[1][1];
			for(int i=0;i<2;i++)
				for(int j=0;j<2;j++)
					tot[i][j]%=mod;
		}
		for(int i=0;i<2;i++)
			for(int j=0;j<2;j++)
				now[i][j]=s[i][j];
		s[0][0]=now[0][0]*now[0][0]+now[0][1]*now[1][0];
		s[0][1]=now[0][0]*now[0][1]+now[0][1]*now[1][1];
		s[1][0]=now[1][0]*now[0][0]+now[1][1]*now[1][0];
		s[1][1]=now[1][0]*now[0][1]+now[1][1]*now[1][1];
		for(int i=0;i<2;i++)
			for(int j=0;j<2;j++)
				s[i][j]%=mod;
		g/=2;
	}
	printf("%lld",(tot[0][0]+tot[1][0])%mod);
}


你可能感兴趣的:(斐波那契公约数,洛谷之提高历练地,数论(3-5))