题目描述
Tn=1*f1+2*f2+3*f3+……+n*fn (fn为斐波拉契的第n项值)
现在GM想请你帮忙求Tn%m的值
比如 N = 5 M = 5 输出为1
T5 = (1*1+2*1+3*2+4*3+5*5)%5 = 46%5 = 1
矩阵加速复习
我首先就想啊,既然要用矩阵加速,那么要满足什么?
你不知道就看看这个https://blog.csdn.net/qq_41814502/article/details/88946866
由于B矩阵要固定,所以肯定是要找出固定的DP方程
我们不妨把G[N] = N * F[N]
我们发现,G[N-2] = (N-2) * F[N-2] G[N-1] = (N-1) * F[N-1]
大家发现,要让G[N-2] 和 G[N-1] 变成G[N] 差了两个F[N-2] 1个F[N-1]
F[N-2] 和 F[N-1] 好求吧!所以我们要矩阵加速其实就是要找到固定的B,就是这样!
真正的题解
将A变成 A11 => S[N-1] A12 => F[N-2] A13 => F[N-1] A14 => G[N-2] A15 => G[N-1]
这里的S[N] = G[1] + ...... G[N]的前缀和,就是答案嘛!
我们先看C15 => G[N]
A15 => G[N-1]
C15 => 0S[N-1] + 2F[N-2] + F[N-1] + G[N-2] + G[N-1] => 0 2 1 1 1
A14 => G[N-2] C14 => G[N-1] => 0 0 0 0 1
A13 => F[N-1] C13 => F[N] => F[N-2] + F[N-1] => 0 1 1 0 0
A12 => F[N-2] C12 => F[N-1] = > 0 0 1 0 0
A11 => S[N-1] C11 => S[N] => S[N-1] + G[N] => S[N-1] + C15 = > 1 2 1 1 1
大家难道不懂为什么就变成后面的数字吗?
其实5个数字分别表示在A的基础上,第N个数字表示C在A的基础上要多少个AN
比如C15 我们不要A11(S[N-1) 就是0
要2个F[N-2] 也就是A12 就是2
要1个F[N-1] 也就是A13 就是1
后面自然一样的吧!就是 0 2 1 1 1
我们的B =.
1 0 0 0 0
2 0 1 0 2
1 1 1 0 1
1 0 0 0 1
1 0 0 1 1
大家都知道,排的时候是竖着的,大家可以看看https://blog.csdn.net/qq_41814502/article/details/88946866(其实是......)
末尾
我发现其他人的方法也是千奇百怪,在https://blog.csdn.net/qq_41814502/article/details/88946866这篇博客也说过
矩阵加速自然方法多,大家也不要嘘嘘了!
大家代码应该会打了吧
我们就这样 答案为A * B^(N-2)
A = 3 1 1 1 2 为什么你自己不会推啊! 1*1+2*1 = 3 1 1 1*1 2*1
B^(N-2) => quickpow 自然里面的初始值为主对线权为1, 倍增的数就是上面的B数组了!
就是这样(伪代码)
ans = 主对角线为1, tot = B;
while(y){
if(y & 1)
ans = ans * tot;
tot = tot * tot;
y >>= 1;
}
return ans;
printf(????????? a(就是3 1 1 1 2)*ans);
感谢大家阅读,不当之处多指出!要点赞关注转发哦!