【HDU 1021】Fibonacci Again(矩阵快速幂水题)

Fibonacci Again

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 69786    Accepted Submission(s): 32055


Problem Description
There are another kind of Fibonacci numbers: F(0) = 7, F(1) = 11, F(n) = F(n-1) + F(n-2) (n>=2).
 

Input
Input consists of a sequence of lines, each containing an integer n. (n < 1,000,000).
 

Output
Print the word "yes" if 3 divide evenly into F(n).

Print the word "no" if not.
 

Sample Input
 
  
0 1 2 3 4 5
 

Sample Output
 
  
no no yes no no no
 

Author
Leojay
 

看到这道题第一眼想到的就是矩阵快速幂,可能有更加巧妙的方法,但我还是直接暴力对每一项对3求余(在求F[n]的过程中)

然后直接判断F[n]是否为0

#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 100
typedef long long ll;
struct mat
{
	ll m[MAXN][MAXN];
}unit;
ll n;
mat msub(mat a,mat b)
{
	mat ret;
	ll x;
	for(int i=0;i<4;i++)
	{
		for(int j=0;j<4;j++)
		{
			x=0;
			for(int k=0;k<4;k++)
			{
				x+=(a.m[i][k]*b.m[k][j])%3;
			}
			ret.m[i][j]=x%3;
		}
	}
	return ret;
}

void init_unit()
{
	for(int i=0;i<MAXN;i++)
	{
		unit.m[i][i]=1;
	}
}

mat qpow(mat a,ll x)
{
	mat ans=unit;
	while(x)
	{
		if(x&1) ans=msub(a,ans);
		a=msub(a,a);
		x>>=1;
	}
	return ans;
}

int solve(ll n)
{
	mat a;
	a.m[0][0]=1;
	a.m[0][1]=1;
	a.m[1][0]=1;
	a.m[1][1]=0;
	mat b;
	b.m[0][0]=11;
	b.m[0][1]=7;
	b.m[1][0]=7;
	b.m[1][1]=0;
	mat ans;
	ans=msub(qpow(a,n-1),b);
	return ans.m[0][0]; 
}
int main()
{
	init_unit();
	while(cin>>n)
	{
		if(!n) cout<<"no"<<endl;
		else
		{
		   if(solve(n)) cout<<"no"<<endl;
		   else cout<<"yes"<<endl;	
		}
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/duanghaha/article/details/80280375