佳佳的 Fibonacci

link

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;
}
posted @ 2022-06-23 13:12  Feyn618  阅读(39)  评论(0编辑  收藏  举报