首页 > 其他分享 >佳佳的 Fibonacci 题解

佳佳的 Fibonacci 题解

时间:2023-06-10 17:33:36浏览次数:49  
标签:mat 佳佳 题解 矩阵 nF int Fibonacci 递推

佳佳的 Fibonacci 题解

题目:

image


题解:

数据范围很大,暴力超时,考虑的是矩阵优化递推,关键是求出递推矩阵,然后结合矩阵快速幂求解
如何求解递推矩阵?
我们首先知道斐波那契的递推式:

f[i]=f[i-1]+f[i-2]——>①

然后题目中给我们了T(n)的递推式:

T(n)=F[1]+2F[2]+3F[3]+...+nF[n]——>②

考虑从T(n)推得T(n+1)

T(n+1)=T(n)+(n+1)*F[n+1]

由①的:

T(n+1)=T(n)+(n+1)*(F[n]+F[n-1])=T(n)+n*F[n]+n*F[n-1]+F[n]+F[n-1])

我选择T[n-1],nF[n],nF[n-1],F[n],F[n-1]作为行向量
从而推出T[n],(n+1)F[n+1],(n+1)F[n],F[n+1],F[n];
我们现在需要找出底数矩阵A,它的规模应该是5*5的(显然

下面请填表:

T(n-1) nF[n] nF[n-1] F[n] F[n-1]
T(n+1)
(n+1)F[n+1]
(n+1)F[n]
F[n+1]
F[n]

填完应该长这样:

T(n-1) nF[n] nF[n-1] F[n] F[n-1]
T(n+1) 1 1 0 0 0
(n+1)F[n+1] 0 1 1 1 1
(n+1)F[n] 0 1 0 1 0
F[n+1] 0 0 0 1 1
F[n] 0 0 0 1 0

转置一下,就得到了矩阵A:

1 0 0 0 0
1 1 1 0 0
0 1 0 0 0
0 1 1 1 1
0 1 0 1 0

然后可以得出:

{T(n) (n+1)F[n+1] (n+1)F[n] F[n+1] F[n]

=A^(n-1) * {T(2) 2F[2] 2F[1] F[2] F[1]}

这就是初始矩阵:

{3 3 3 1 1}


代码实现也很容易,注意A要转置(矩阵乘行向量)了解更多
给出代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define il inline
int n,mod;
il int read(){
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
il void write(int x){
    if(x<0)putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
    return;
}
struct mat{
    int m[10][10];
    mat(){
        memset(m,0,sizeof(m));
    }
};
mat operator*(const mat& a,const mat& b){
    mat c;
    for(int i=1;i<=5;i++)
        for(int j=1;j<=5;j++)
            for(int k=1;k<=5;k++)
                c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
    return c;
}
il mat fast_pow(int b){
    mat a,zero;
    a.m[1][1]=1;
    a.m[2][1]=1;
    a.m[3][1]=1;
    a.m[2][2]=1;
    a.m[3][2]=1;
    a.m[4][2]=1;
    a.m[5][2]=1;
    a.m[2][3]=1;
    a.m[4][3]=1;
    a.m[4][4]=1;
    a.m[5][4]=1;
    a.m[4][5]=1;
    zero.m[1][1]=3;
    zero.m[1][2]=3;
    zero.m[1][3]=3;
    zero.m[1][4]=1;
    zero.m[1][5]=1;
    while(b){
        if(b&1) zero=zero*a;
        b>>=1;
        a=a*a; 
        // for(int i=1;i<=5;i++){
        //     for(int j=1;j<=5;j++){
        //         cerr<<zero.m[i][j]<<" ";
        //     }
        //     cerr<<endl;
        // }
    }
    return zero;
}
main(void){
    n=read(),mod=read();
    if(n==1){
        cout<<1<<endl;
        return 0;
    }
    mat ans=fast_pow(n-2);
    write(ans.m[1][1]%mod);
}

标签:mat,佳佳,题解,矩阵,nF,int,Fibonacci,递推
From: https://www.cnblogs.com/cccomfy/p/17471629.html

相关文章

  • 题解 NOD2207C【不降序列】
    problem给出n个数组A1​到An​,数组中的元素为1到M之间的数字。数组之间也存在字典序,即从第一个数开始逐位比较,一旦某个数字大于另一个,则数组的字典序大于另一个,如果某一个是另一个的前缀,则前缀的字典序更小。你可以选择一些大于0的数字执行减法操作,一旦选中某个数......
  • 题解 NOD2207D【电报】
    前置知识:高斯消元已知\(n\)元线性一次方程组。关于\(x_1,x_2,\cdots,x_n\)。\[\begin{cases}a_{1,1}x_1+a_{1,2}x_2+\cdots+a_{1,n}x_n=b_1\\a_{2,1}x_1+a_{2,2}x_2+\cdots+a_{2,n}x_n=b_2\\\cdots\\a_{n,1}x_1+a_{n,2}x_2+\cdots......
  • [SHOI2011]双倍回文 题解
    [SHOI2011]双倍回文题解看了一些写回文自动机的大佬的代码,我深感敬畏,于是我转身向Manacher走去现在荣登最优解第一页……说实话,这个方法的复杂度是很玄学的,但是加了一些优化之后,就几乎不可能被卡到\(O(n^2)\)了。具体思路如下:预处理字符串部分就略过吧我们预先跑一......
  • P7959 [COCI2014-2015#6] WTF 题解
    P7959[COCI2014-2015#6]WTF题解呃,是一道DP题说实话,原题实际上是不要输出一种方法的……但是似乎放这道题的人想增加一点难度?这里有两种做法,但都是DP。预备观察我们首先观察一些性质,以方便解题。循环不变:我们可以观察到,在\(n\)次变换后,序列会还原。也就是说,两个......
  • 题解 BZOJ4399 魔法少女LJJ
    前言XXX:你瞅你长得那个B样,俺老孙就(氧化钙)......这魔法(J8)少女能不能去死啊啊啊啊啊啊啊啊啊啊......正文"LJJ你是来搞笑的吧"你说得对,但是这数据就是骗人的.首先看题面:然后看样例:最后看数据范围:我惊奇的发现\(c\le7\)!家人们我真难绷qaq...问题分析显......
  • [AGC055B] ABC Supremacy 题解
    [AGC055B]ABCSupremacy题解题目描述给定两个长度为 \(n\) 的字符串 \(a\),\(b\)。你可以进行若干次以下操作:若 \(a\) 中的一个子串为 ABC,BCA 或 CAB,那么可以将这个子串替换为 ABC,BCA 或 CAB。求能否将 \(a\) 变成 \(b\),输出 YES 或 NO。解析不难发现,......
  • chrome 跨域问题解决
    1.后端设置了跨域,https下可以,http不可以高版本chrome配置了策略,如果访问私有网络,会出现禁止跨域chrome://flags/#block-insecure-private-network-requestsBlockinsecureprivatenetworkrequests.......
  • JAVA面试题解惑系列(六)——字符串(String)杂谈
    关键字:java面试题字符串string作者:臧圩人(zangweiren)网址:http://zangweiren.javaeye.com上一次我们已经一起回顾了面试题中常考的到底创建了几个String对象的相关知识,这一次我们以几个常见面试题为引子,来回顾一下String对象相关的其它一些方面。String的l......
  • quickfix协议当有中文时校验位错误问题解决
    quickfix校验位计算都是根据ISO-8859-1编码计算,知道这个规则后续我们处理中文就很好处理了。但是如果用ISO-8859-1编码有中文会出现乱码,如果将CharsetSupport.setCharset设置为UTF-8或者GBK时,在发送数据时会报java.nio.bufferoverflowexception:null,或者校验位失败。1、往step网......
  • JSOI2018 部分题解
    目录潜入行动防御网络列队潜入行动一眼直接DP。设\(f_{i,j,0/1,0/1}\)表示\(i\)子树内放了\(j\)个监听设备,\(i\)是否被子结点覆盖,\(i\)是否放了监听设备,\(i\)子树内除了\(i\)都被覆盖的方案数。转移是一个树形背包,时间复杂度\(\mathcal{O}(nk)\),只是常数有点大。......