问题描述:
已知斐波那契数列 Fn=Fn−1+n−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
斐波那契数列可以通过矩阵快速幂来求解
所以问题就转化为了求矩阵[1 1][1 0]的n-2次方再乘以[1 1]
如何求指数很大的幂呢,这里有一个知识点叫做快速幂,可以自行搜索一下
详细代码如下
import java.io.BufferedInputStream;
import java.util.Scanner;
public class Main {
public static final int mod = 998244353;
public static long[][] a= {{1,1},{1,0}};//底数
public static void main(String[] args) {
long[][] result= {{1},{1}};
Scanner in = new Scanner(new BufferedInputStream(System.in));
long n = in.nextLong();
if(n==1||n==2) {
System.out.println(1);
return;
}else {
n-=2;
//快速幂的知识,可自行搜索
while(n>0) {
if((n&1)==1) {//如果n是奇数,就抽出来一个
result=Muti(a, result);
}
n>>=1;//n缩小两倍
a=Muti(a, a);//底数扩大为原来的平方
}
System.out.println(result[0][0]);
}
}
//两个矩阵相乘
public static long[][] Muti(long[][] a,long[][] b){
final int rows=a.length;//第一个矩阵的行数
final int cols=b[0].length;//第二个矩阵的列数
final int temp=a[0].length;//第一个矩阵的列数
long[][] result =new long[rows][cols];//创建一个新的二维数组存储结果
for(int i=0;i<rows;i++) {
for(int j=0;j<cols;j++) {
for(int k=0;k<temp;k++) {
result[i][j]+=a[i][k]*b[k][j];
result[i][j]%=mod;
}
}
}
return result;
}
}