佳佳的 Fibonacci
loj那么贫瘠的土地上竟然还能长出洛谷没有的花。这是我第一篇记录loj上题目的随笔。
首先之前学过一个小结论,对本题的解决有极大的帮助,但我考场上竟竟竟然忘了,于是拿了60分的部分分跑路了……
一开始的那个函数T不是很好推关系,直接上矩阵乘法不是很好弄,于是考虑推柿子:
首先有结论:
\[\sum\limits_{i=1}^NF_i=F_{i+2}
\]
所以
\[T_N=\sum\limits_{i=1}^Ni\times F_i\\=\sum\limits_{i=1}^N(N-N+i)\times F_i\\=N\times\sum\limits_{i=1}^NF_i-\sum\limits_{i=1}^{N-1}(N-i)\times F_i\\=N\times F_{N+2}-\sum\limits_{i=1}^{N-1}F_{i+2}-1\\=N\times F_{N+2}-\sum\limits_{i=1}^{N+1}F_i+1\\=N\times F_{N+2}-F_{N+3}+2
\]
用矩阵快速幂即可。
压了一点行。
#include<cstdio>
#define int long long
#define F(A) for(int A=1;A<=2;A++)
int m,mod;
struct node{int a[3][3];}ne;
node operator *(node s1,node s2){
node an=ne;
F(i)F(j)F(k)an.a[i][j]+=s1.a[i][k]*s2.a[k][j],an.a[i][j]%=mod;
return an;
}
node qpow(node s1,int s2){
if(s2==1)return s1;
node an=qpow(s1,s2>>1);
if(s2&1)return an*an*s1;
else return an*an;
}
signed main(){
node ss=ne;ss.a[1][1]=ss.a[1][2]=ss.a[2][1]=1;
scanf("%lld%lld",&m,&mod);node an=qpow(ss,m+1);
int f2=an.a[2][1]+an.a[2][2],f3=an.a[1][1]+an.a[1][2];
printf("%lld",(m*f2-f3+2)%mod);return 0;
}
一如既往,万事胜意