您的位置:首页 > 其它

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

2016-06-28 22:53 169 查看


H. zzblack与斐波那契数列

Case Time Limit: 3000ms

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

Submit Status PID:
21466

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];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: