专栏文章
题解:P12847 [蓝桥杯 2025 国 A] 斐波那契数列
P12847题解参与者 2已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mip30lqb
- 此快照首次捕获于
- 2025/12/03 05:20 3 个月前
- 此快照最后确认于
- 2025/12/03 05:20 3 个月前
题目传送门
思路
看到 ,我会矩阵加速!很遗憾,递推式中包含乘号,我们无法加速它。但它求的答案是乘积?所以也许我们能从指数上找规律。直接打表:
不难看出,左边的指数为斐波那契数列,满足 。右边的指数满足 。于是我们就可以矩阵加速计算这两个递推式。关键是指数需要取模,怎么办?有欧拉定理:
这样我们对递推式计算的结果取模 即可。时间复杂度 ,其中 为矩阵边长,本题可以理解为 。
Code
CPP#include <bits/stdc++.h>
using namespace std;
#define il inline
typedef long long ll;
const int N = 3, mod = 998244353;
int len;
struct node
{
ll a[N][N];
friend node operator * (const node &n1, const node &n2)
{
node n3 = (node){{{0}}};
for(int i = 0;i < len;++i)
for(int j = 0;j < len;++j)
for(int k = 0;k < len;++k)
n3.a[i][j] = (n3.a[i][j] + n1.a[i][k] * n2.a[k][j] % (mod - 1)) % (mod - 1);
return n3;
}
};
il node matpow(node A, node T, ll n)
{
while(n)
{
if(n & 1) A = A * T;
T = T * T;
n >>= 1;
}
return A;
}
il ll f1(ll n)
{
if(n <= 0) return 0;
if(n <= 2) return 1;
node T = (node){{
{1, 1},
{1, 0}
}};
node A = (node){{
{1, 0},
{0, 1}
}};
len = 2;
node ans = matpow(A, T, n - 2);
return (ans.a[0][0] + ans.a[0][1]) % (mod - 1);
}
il ll f2(ll n)
{
if(n == 1) return 0;
node T = (node){{
{1, 1, 1},
{1, 0, 0},
{0, 0, 1}
}};
node A = (node){{
{0, 0, 0},
{0, 0, 0},
{1, 0, 0}
}};
node B = (node){{
{1, 0, 0},
{0, 1, 0},
{0, 0, 1}
}};
len = 3;
node ans = matpow(B, T, n - 1) * A;
return ans.a[0][0];
}
il ll fastpow(ll a, ll b)
{
ll ans = 1;
for(;b > 0;b >>= 1, a = a * a % mod)
if(b & 1) ans = ans * a % mod;
return ans;
}
int main()
{
ll n;cin >> n;
// cout << f1(n) << " " << f2(n) << "\n";
if(n == 1) cout << 2;
else cout << fastpow(2, f1(n)) * fastpow(3, f2(n)) % mod;
return 0;
}
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...