【Loj #10222. 「一本通 6.5 例 4」佳佳的 Fibonacci】题解
题目链接
题目
佳佳对数学,尤其对数列十分感兴趣。在研究完 Fibonacci 数列后,他创造出许多稀奇古怪的数列。例如用 表示 Fibonacci 前 项和 的值,即 ,其中 。可这对佳佳来说还是小菜一碟。
终于,她找到了一个自己解决不了的问题。用 表示 Fibonacci 数列前 项变形后的和 的值。
现在佳佳告诉你了一个 和 ,请求出 的值。
思路
设
由 :
可得:
由 可得:
故可以用矩阵快速幂算出 和 。
列出矩阵:
总结
这是一道挺好的矩阵快速幂的题,既有思维含量,又有算法含量。
首先思维方面,这题可以巧妙的转化 ,把一个难求的值变成两个易求的值相减。
另一方面,矩阵快速幂也调了我很久,一个 的矩阵和一个 的矩阵相乘,三层循环分别是 ,注意顺序。
Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n, m, i, j, k;
int a[5][5]= {
{0,0,0,0,0},
{0,1,1,0,0},
{0,1,0,0,0},
{0,1,0,1,0},
{0,0,0,1,1}
};
int ans[5][5], mo;
void cheng(int a[5][5], int b[5][5], int n, int m, int q) {
int c[5][5]= {0}, i, j, k;
for(i=1; i<=n; ++i)
for(j=1; j<=q; ++j)
for(k=1; k<=m; ++k)
c[i][j]=(c[i][j]+a[i][k]*b[k][j])%mo;
memset(a, 0, sizeof(c));
memcpy(a, c, sizeof(c));
}
signed main() {
scanf("%lld%lld", &n, &mo); m=n;
ans[1][1]=ans[2][2]=ans[3][3]=ans[4][4]=1;
while(n) {
if(n&1) cheng(ans, a, 4, 4, 4);
n>>=1; cheng(a, a, 4, 4, 4);
}
memset(a, 0, sizeof(a)); a[1][1]=1;
cheng(ans, a, 4, 4, 1);
printf("%lld", ((ans[3][1]*m-ans[4][1])%mo+mo)%mo);
return 0;
}
本文来自博客园,作者:zhangtingxi,转载请注明原文链接:https://www.cnblogs.com/zhangtingxi/p/15789018.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战