M斐波那契数列 HDU - 4549

原题链接
考察:矩阵快速幂
错误思路:
  想着取对数,然后半天做不出来()
正确思路:
  随着f[i]的i变大,a,b的指数是斐波那契数列,再用欧拉降幂+快速幂即可.

Code

#include <iostream> 
#include <cstring>
using namespace std;
typedef long long LL;
const int M = 1000000006,N=2,Mod = M+1;
int c,d,n;
void mul(int f[],int a[][N])
{
	int res[N] = {0};
	for(int i=0;i<N;i++)
	  for(int j=0;j<N;j++)
	   res[i] = (res[i]+(LL)f[j]*a[j][i])%M;
	memcpy(f,res,sizeof res);
}
void mul(int a[][N])
{
	int res[N][N] = {0};
	for(int i=0;i<N;i++)
	  for(int j=0;j<N;j++)
	    for(int k=0;k<N;k++)
	     res[i][j] = (res[i][j]+(LL)a[i][k]*a[k][j])%M;
	memcpy(a,res,sizeof res);
}
LL qsm(int a,int k)
{
	LL res = 1;
	while(k)
	{
		if(k&1) res = res*a%Mod;
		a = (LL)a*a%Mod;
		k>>=1;
	}
	return res;
}
int main()
{
	while(scanf("%d%d%d",&c,&d,&n)!=EOF) 
	{
		if(!c||!d) {puts("0");continue;} 
		if(n==1) {printf("%d\n",d%Mod);continue;} 
		if(!n) {printf("%d\n",c%Mod);continue;} 
		n--;
		int f[N] = {1,0};
		int a[N][N] = {
		   {1,1},
		   {1,0} 
		};
		while(n)
		{
			if(n&1) mul(f,a);
			mul(a);
			n>>=1;
		}
		printf("%lld\n",qsm(c,f[1])*qsm(d,f[0])%Mod);
	}
	return 0;
}

posted @ 2021-06-09 16:17  acmloser  阅读(30)  评论(0编辑  收藏  举报