已知斐波那契数列 Fn=Fn−1+Fn−2(n>=3),F1=1,F2=1
求解该数列的第n项,结果对998244353取模。
提示:矩阵快速幂,unsigned long long的最大值:1844674407370955161(1.8e18)
输入格式:
输入一个正整数n (1<=n<=1e18)。
输出格式:
输出一个数,数列的第n项
输入样例1:
1
结尾无空行
输出样例1:
1
结尾无空行
输入样例2:
3
结尾无空行
输出样例2:
2
结尾无空行
#include<stdio.h>
#define Max 998244353
struct juzhen
{
unsigned long long M[2][2];
};//定义结构体
struct juzhen mul(struct juzhen A, struct juzhen B)//矩阵相乘,返回值为矩阵
{
struct juzhen C;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
C.M[i][j] = 0;//初始化新矩阵
for (int k = 0; k < 2; k++)
{
C.M[i][j] = C.M[i][j] + A.M[i][k] * B.M[k][j];
C.M[i][j] = C.M[i][j] % Max;
}
}
}
return C;//将乘积结果返回
}
struct juzhen qul(unsigned long long t, struct juzhen a)//快速幂算法
{
struct juzhen res;
res.M[0][0] = 1; res.M[0][1] = 0;
res.M[1][0] = 0; res.M[1][1] = 1;//单位矩阵
while (t > 0)
{
if (t % 2)
res = mul(res, a);
a = mul(a, a);
t = t>>1;//用移位操作可以进一步较少程序执行时间
}
return res;
}
int main()
{
unsigned long long N, sum = 0;
scanf("%llu", &N);
struct juzhen A;
struct juzhen D;
A.M[0][0] = 1;
A.M[0][1] = 1;
A.M[1][0] = 1;
A.M[1][1] = 0;//赋初值
if (N == 1 || N == 2) printf("1");
else
{
D = qul(N - 2, A);
sum = (D.M[0][0] + D.M[0][1]) % Max;
printf("%llu", sum);
}
return 0;
}
运行结果:
这道题的难度在与矩阵要定义为结构体,因为结构体是可以有返回值的。这是一个难点。另外矩阵的乘法这个算法也是个难点。矩阵快速幂的算法也有难度。总体来说,这道题的难度很大。请读者在阅读的同时仔细思考体会。