题目链接
新型斐波那契数列
题目描述
新型斐波那契数列的第一、二、三项都为 1 1 1 ,从第四项起每一项等于前面三项之和,求此数列第 n n n 项模 m m m 的余数。
输入描述
输入一行为两个整数 n n n 、 m m m ,用空格隔开。
输出描述
输出一行为新型斐波那契数列第 n n n 项模 m m m 的余数。
输入输出样例
输入
7 3
输出
2
数据范围
- 1 ⩽ n ⩽ 1 0 18 1\leqslant n\leqslant 10^{18} 1⩽n⩽1018
- 1 ⩽ m ⩽ 100 1\leqslant m\leqslant 100 1⩽m⩽100
解题思路
矩阵快速幂
根据题意,假设这个新型斐波那契数列 F F F 有 n n n 项(下标起始为 1 ),那么有如下递推式:
F n = { 1 n ⩽ 3 F n − 3 + F n − 2 + F n − 1 n > 3 F_n=\begin{cases} 1 \qquad \qquad \qquad \qquad \ n\leqslant 3\\ F_{n-3}+F_{n-2}+F_{n-1}\,\, n>3\\ \end{cases} Fn={1 n⩽3Fn−3+Fn−2+Fn−1n>3
1、动态规划——按照表达式直接递推,时间复杂度为 O ( n ) O(n) O(n) 。由于 n n n 的数据范围较大,会超时。
2、矩阵快速幂
对数列的前几项计算, F 1 = F 2 = F 3 = 1 , F 4 = 3 , F 5 = 5 , F 5 = 9 F_{1}=F_{2}=F_{3}=1,F_{4}=3,F_{5}=5,F_{5}=9 F1=F2=F3=1,F4=3,F5=5,F5=9
矩阵形式:
[ F 2 F 3 F 4 ] = [ 0 1 0 0 0 1 1 1 1 ] ⋅ [ F 1 F 2 F 3 ] \left[ \begin{array}{c} F_2\\ F_3\\ F_4\\ \end{array} \right] =\left[ \begin{matrix} 0& 1& 0\\ 0& 0& 1\\ 1& 1& 1\\ \end{matrix} \right] \cdot \left[ \begin{array}{c} F_1\\ F_2\\ F_3\\ \end{array} \right] \quad F2F3F4 = 001101011 ⋅ F1F2F3
[ F 3 F 4 F 5 ] = [ 0 1 0 0 0 1 1 1 1 ] ⋅ [ F 2 F 3 F 4 ] \quad \left[ \begin{array}{c} F_3\\ F_4\\ F_5\\ \end{array} \right] =\left[ \begin{matrix} 0& 1& 0\\ 0& 0& 1\\ 1& 1& 1\\ \end{matrix} \right] \cdot \left[ \begin{array}{c} F_2\\ F_3\\ F_4\\ \end{array} \right] \,\, F3F4F5 = 001101011 ⋅ F2F3F4
于是有 [ F 3 F 4 F 5 ] = [ 0 1 0 0 0 1 1 1 1 ] 2 ⋅ [ F 1 F 2 F 3 ] \left[ \begin{array}{c} F_3\\ F_4\\ F_5\\ \end{array} \right] =\left[ \begin{matrix} 0& 1& 0\\ 0& 0& 1\\ 1& 1& 1\\ \end{matrix} \right] ^2\cdot \left[ \begin{array}{c} F_1\\ F_2\\ F_3\\ \end{array} \right] F3F4F5 = 001101011 2⋅ F1F2F3
将上述情况推广到 n n n项,有 [ F n − 2 F n − 1 F n ] = [ 0 1 0 0 0 1 1 1 1 ] n − 3 ⋅ [ F 1 F 2 F 3 ] \left[ \begin{array}{c} F_{n-2}\\ F_{n-1}\\ F_n\\ \end{array} \right] =\left[ \begin{matrix} 0& 1& 0\\ 0& 0& 1\\ 1& 1& 1\\ \end{matrix} \right] ^{n-3}\cdot \left[ \begin{array}{c} F_1\\ F_2\\ F_3\\ \end{array} \right] Fn−2Fn−1Fn = 001101011 n−3⋅ F1F2F3
记 3 × 3 3\times3 3×3大小矩阵 A A A,其中 A = [ 0 1 0 0 0 1 1 1 1 ] A=\left[ \begin{matrix} 0& 1& 0\\ 0& 0& 1\\ 1& 1& 1\\ \end{matrix} \right] A= 001101011
采用矩阵快速幂的方法快速计算出 F n F_{n} Fn 的值,由于 A A A 为固定的 3 × 3 3\times3 3×3 大小,因此复杂度为 O ( log n ) O(\log n) O(logn) 。
输出
1、当输入的 n n n 小于等于 3 时,可以直接输出 1 返回结果;
2、当输入的 n n n 大于3 时,利用矩阵快速幂计算出 A n − 3 A^{n-3} An−3 ,由于 F 1 = F 2 = F 3 = 1 F_{1}=F_{2}=F_{3}=1 F1=F2=F3=1 ,因此可以直接将 A n − 3 A^{n-3} An−3 的最后一行求和,该结果即为 F n F_{n} Fn 。
AC Code
# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
import sys
N,M=map(int,input().split())class matrix:def __init__(self,m:list(list())):self.m=mdef __mul__(self,other): #运算符 * 的重载re=[[0,0,0],[0,0,0],[0,0,0]]for i in range(3):for j in range(3):for k in range(3):re[i][j]=(re[i][j]+self.m[i][k]*other.m[k][j])%Mreturn matrix(re)def pow_matrix(a:matrix,n:int): #矩阵快速幂ans=matrix([[1,0,0],[0,1,0],[0,0,1]])while n:if n&1:ans=ans*aa=a*an>>=1return ansif N<=3:print(1)sys.exit(0)
bas=matrix([[0,1,0],[0,0,1],[1,1,1]])
res_mat=pow_matrix(bas,N-3)fres=(res_mat.m[2][0]+res_mat.m[2][1]+res_mat.m[2][2])%M
print(fres)