现在的位置: 首页 > 综合 > 正文

HDU4549

2013年11月05日 ⁄ 综合 ⁄ 共 1639字 ⁄ 字号 评论关闭

M斐波那契数列

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 560    Accepted Submission(s): 156

Problem Description
M斐波那契数列F[n]是一种整数数列,它的定义如下:

F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )

现在给出a, b, n,你能求出F[n]的值吗?

 

 

Input
输入包含多组测试数据;
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )
 

 

Output
对每组测试数据请输出一个整数F[n],由于F[n]可能很大,你只需输出F[n]对1000000007取模后的值即可,每组数据输出一行。
 

 

Sample Input
0 1 0 6 10 2
 

 

Sample Output
0 60

 

//尽管知道矩阵的快速幂和一般数的快速幂,但数论太差,以为a^k%mod=a^(k%mod)%mod,其实这是大错特错,好像可以根据欧拉函数推出a^k%mod=a^(k%(mod-1))%mod

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream> 
using namespace std;
const int mod=1000000007;

//N表示矩阵的N次幂
int aa,bb,N;
//此处假设矩阵为3*3阶
//origin存放需计算的矩阵,res存放答案矩阵
struct matrix
{
	__int64 a[3][3];
}origin,res;

//直接将2个矩阵相乘x*y,返回计算后的矩阵
matrix multiply(matrix x,matrix y)
{
	matrix temp;
	memset(temp.a,0,sizeof(temp.a));
	for(int i=0;i<2;i++)
	{
		for(int j=0;j<2;j++)
		{
			for(int k=0;k<2;k++)
			{
				temp.a[i][j]+=x.a[i][k]*y.a[k][j];
				temp.a[i][j]=temp.a[i][j]%(mod-1);
			}
		}
	}
	return temp;
}

//将res初始化为单位矩阵,人为输入origin
void init()
{
	origin.a[0][0]=origin.a[0][1]=origin.a[1][0]=1;
	origin.a[1][1]=0;
	//将res.a初始化为单位矩阵 
	memset(res.a,0,sizeof(res.a));
	res.a[0][0]=res.a[1][1]=1;                  
}

//矩阵快速幂的计算
void calc(int n)
{
	while(n)
	{
		if(n&1)
			res=multiply(res,origin);
		n>>=1;
		origin=multiply(origin,origin);
	}
}

__int64 optimized_pow_n(__int64 x, __int64 n)
{
    __int64  pw = 1;
    while (n > 0)
	{
        if (n & 1)       
            pw *= x;
		pw=pw%mod;
        x *= x;
		x=x%mod;
        n >>= 1;     
    }
    return pw;
}



int main()
{
    while(cin>>aa>>bb>>N)
    {
		init();
		calc(N);
	//	printf("%I64d    %I64d\n",res.a[0][1],res.a[1][1]);

		__int64 temp1=optimized_pow_n((__int64)aa,(__int64)res.a[1][1]);
		__int64 temp2=optimized_pow_n((__int64)bb,(__int64)res.a[0][1]);
		__int64 temp=(temp1%mod)*(temp2%mod)%mod;
		printf("%I64d\n",temp);
    }
    return 0;
}

抱歉!评论已关闭.