题目传送门
没见过这玩意,写个题解记下。
题目大意
周知斐波那契数列定义为:
fib(n)={1n≤2fib(n−1)+fib(n−2)n>2
然后定义(n≤0 函数值为 0)
f(n)=n∑i=1fib(i)
你需要求出:
n∑i=1fib(i)(f(i−2)+fib2(i)+fib(i))
数据范围 n≤1018,数据组数 T≤2×105,模数 2≤p≤109+7
题目解析
第一次见这种题目,记录一下。

从这张图我们可以得到
f(n)=n∑i=1(fib(i))2=fib(n)fib(n+1)
然后就是化式子
n∑i=1fib(i)(f(i−2)+fib2(i)+fib(i))展开f(x)=n∑i=1fib(i)(fib(i−2)fib(i−1)+fib2(i)+fib(i))乘开,提出∑fib2(i)=n∑i=1(fib(i)fib(i−1)fib(i−2)+fib3(i))+n∑i=1fib2(i))左边带入fib(i−2)=fib(i)−fib(i−1),右边带入上述公式=n∑i=1(fib(i)fib(i−1)(fib(i)−fib(i−1))+fib3(i))+fib(n)fib(n+1)乘开=n∑i=1(fib2(i)fib(i−1)−fib(i)fib2(i−1)+fib3(i))+fib(n)fib(n+1)提取公因式fib2(i)=n∑i=1(fib2(i)(fib(i−1)+fib(i))−fib(i)fib2(i−1))+fib(n)fib(n+1)合并fib(i−1)+fib(i)=fib(i+1)=n∑i=1(fib2(i)fib(i+1)−fib2(i−1)fib(i))+fib(n)fib(n+1)裂项相消=fib2(n)fib(n+1)−fib2(0)fib(1)+fib(n)fib(n+1)通过fib(n)=fib(n−1)+fib(n−2)逆推得到fib(0)=0并带入=fib2(n)fib(n+1)+fib(n)fib(n+1)
矩阵乘法一次就可以同时算出 fib(n) 和 fib(n+1)。
时间复杂度 O(Tlogn)。
| ll n,p; |
| struct Mat{ |
| ll a11,a12,a21,a22; |
| Mat operator * (const Mat y) const { |
| return (Mat){(this->a11*y.a11+this->a12*y.a21)%p, |
| (this->a11*y.a12+this->a12*y.a22)%p, |
| (this->a21*y.a11+this->a22*y.a21)%p, |
| (this->a21*y.a12+this->a22*y.a22)%p}; |
| } |
| }st,base; |
| Mat pow(Mat x,ll y){ |
| Mat res,tmp=x; res.a11=res.a22=1; res.a12=res.a21=0; |
| while(y){ if(y&1) res=res*tmp; tmp=tmp*tmp; y>>=1; } return res; |
| } |
| void work(){ |
| fin>>n>>p; if(n==1){ fin<<2%p<<'\n'; return; } |
| st.a11=1; st.a12=1; base.a12=1; base.a21=1; base.a22=1; |
| st=(st*pow(base,n-1)); |
| fin<<(st.a11+1)*st.a11%p*st.a12%p<<'\n'; |
| } |
| int main(){ |
| int T; fin>>T; while(T--) work(); return 0; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具