CQUOJ月赛(5月)H题:zzblack与斐波那契数列

H. zzblack与斐波那契数列

Case Time Limit: 3000ms
Memory Limit: 65536KB
64-bit integer IO format:  %lld      Java class name:  Main

zzblack是一个对数学很感兴趣的人。某一天,他在一本生物杂志书上看到了一幅优美的很有规律的图

他立马就反应过来,这就是斐波那契螺旋线,由图中正方形可知,每个正方形的边长等于前面两个之和,设

zzblack想知道第T个正方形的边长

其中:

         

 

因为计算量太大了,于是zzblack求助于你,希望你能借助计算机帮他解决这个问题。

又因为数据很大,所以zzblack只想知道最后答案模上2238065148之后的数。

 
 

Input

  首先输入一个n,表示样例个数。

       接下来n行,每行输入一个整数m (0≤m≤1e18) 。

Output

Sample Input

5
0
1
2
3
4

Sample Output

1
2
13
2584
733149925


一个斐波那契数列第x项的值作为另一个斐波那契数列的第n项......

矩阵快速幂


#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
long long mod;
typedef struct Matrix
{
	long long a[2][2];
	void init()
	{
		memset(a, 0, sizeof(a));
	}
	void unit()
	{
		memset(a, 0, sizeof(a));
		a[0][0] = a[1][1] = 1;		/*单位矩阵*/
	}
}Matrix;
Matrix Fbnc;
Matrix mul(Matrix p1, Matrix p2);
Matrix pow(Matrix p1, long long p);
long long Powto2(long long x);
long long Powto1(long long x);
int main(void)
{
	int T;
	long long n;
	Fbnc.init();
	Fbnc.a[1][0] = Fbnc.a[0][1] = Fbnc.a[1][1] = 1;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%lld", &n);
		mod = 16941960;
		n = Powto2(2*n+1);		/*Powto(x)相当于数列2,1,3,4,7,11,18……中的第x项*/
		mod = 2238065148;
		n = Powto1(n);
		printf("%lld\n" , n);
	}
	return 0;
}

Matrix mul(Matrix p1, Matrix p2)
{
	int i, j, k;
	Matrix c;
	c.init();
	for(i=0;i<=1;i++)
	{
		for(j=0;j<=1;j++)
		{
			for(k=0;k<=1;k++)
				c.a[i][j] = (c.a[i][j]+p1.a[i][k]*p2.a[k][j])%mod;
		}
	}
	return c;
}

Matrix pow(Matrix p1, long long p)
{
	Matrix c; 
	c.unit();
	while(p)
	{
		if((p&1)==1) 
			c = mul(c, p1);
		p = p>>1;
		p1 = mul(p1, p1);
	}
	return c;
}

long long Powto2(long long x)
{
	Matrix P;
	P = Fbnc;
	P = pow(P,x);
	return (P.a[0][1]*2-P.a[0][0]%mod+mod)%mod;
}

long long Powto1(long long x)
{
	Matrix P; 
	P = Fbnc;
	P = pow(P,x);
	return P.a[0][1];
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值