当前位置: 首页 > news >正文

SPOJ - FIBOSUM Fibonacci Sum(递推公式/矩阵快速幂)

传送门


解法一

找规律不难发现斐波那契数列的前缀和和斐波那契数列有直接的联系,也就是 s ( n ) = f ( n + 2 ) − 1 s(n)=f(n+2)-1 s(n)=f(n+2)1,这个可以通过数学归纳法证明或者通过斐波那契数列的公式 f ( n ) = 1 5 [ ( 1 + 5 2 ) n − ( 1 − 5 2 ) n ] f(n)=\frac{1}{\sqrt{5}}[(\frac{1+\sqrt{5}}{2})^n-(\frac{1-\sqrt{5}}{2})^n] f(n)=5 1[(21+5 )n(215 )n],然后考虑等比数列求和公式

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int Mod=1e9+7;

struct Matrix{
    ll matrix[105][105];
};

int n;

Matrix mul(Matrix a,Matrix b){
    Matrix ans;
    memset(ans.matrix,0,sizeof ans.matrix);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    for(int k=1;k<=n;k++){
        ans.matrix[i][j]+=a.matrix[i][k]*b.matrix[k][j]%Mod;
        ans.matrix[i][j]%=Mod;
    }
    return ans;
}

Matrix qkp(Matrix mx,ll x){
    Matrix ans;
    memset(ans.matrix,0,sizeof ans.matrix);
    for(int i=1;i<=n;i++) ans.matrix[i][i]=1;
    while(x){
        if(x&1) ans=mul(ans,mx);
        mx=mul(mx,mx);
        x>>=1;
    }
    return ans;
}


int main(){
    ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int t,l,r;
    Matrix mx;
    n=2;
    mx.matrix[1][1]=1,mx.matrix[1][2]=1;
    mx.matrix[2][1]=1,mx.matrix[2][2]=0;
    cin>>t;
    while(t--){
        cin>>l>>r;
        r+=2,l+=2;
        Matrix res1=qkp(mx,r),res2=qkp(mx,l-1);
        cout<<(res1.matrix[2][1]-res2.matrix[2][1]+Mod)%Mod<<endl;
    }
    return 0;
}

解法二

我们可以得到关于斐波那契前缀和的这样一个递推式:

s ( n ) = s ( n − 1 ) + f ( n ) = s ( n − 1 ) + f ( n − 1 ) + f ( n − 2 ) = s ( n − 1 ) + s ( n − 1 ) − s ( n − 3 ) = 2 ∗ s ( n − 2 ) − s ( n − 3 ) s(n)=s(n-1)+f(n)=s(n-1)+f(n-1)+f(n-2)=s(n-1)+s(n-1)-s(n-3)=2*s(n-2)-s(n-3) s(n)=s(n1)+f(n)=s(n1)+f(n1)+f(n2)=s(n1)+s(n1)s(n3)=2s(n2)s(n3)

即: s ( n ) = 2 ∗ s ( n − 1 ) + 0 ∗ s ( n − 2 ) − 1 ∗ s ( n − 3 ) s(n)=2*s(n-1)+0*s(n-2)-1*s(n-3) s(n)=2s(n1)+0s(n2)1s(n3)

然后又因为:

s ( n − 1 ) = 1 ∗ s ( n − 1 ) + 0 ∗ s ( n − 2 ) + 0 ∗ s ( n − 3 ) s(n-1)=1*s(n-1)+0*s(n-2)+0*s(n-3) s(n1)=1s(n1)+0s(n2)+0s(n3)

s ( n − 2 ) = 0 ∗ s ( n − 1 ) + 1 ∗ s ( n − 2 ) + 0 ∗ s ( n − 3 ) s(n-2)=0*s(n-1)+1*s(n-2)+0*s(n-3) s(n2)=0s(n1)+1s(n2)+0s(n3)

通过一些推导可以得到如下一个矩阵,推导方法见我的博客我们可以得到如下一个矩阵:

[ s ( n ) s ( n + 1 ) s ( n + 2 ) s ( n − 1 ) s ( n ) s ( n + 1 ) s ( n − 2 ) s ( n − 1 ) s ( n ) ] = [ 2 0 − 1 1 0 0 0 1 0 ] n [ s ( 0 ) s ( 1 ) s ( 2 ) s ( 1 ) s ( 0 ) s ( 1 ) s ( − 2 ) s ( − 1 ) s ( 0 ) ] { \left[ \begin{array}{ccc} s(n) & s(n+1) & s(n+2)\\ s(n-1) & s(n) & s(n+1)\\ s(n-2) & s(n-1) & s(n) \end{array} \right ]}={ \left[ \begin{array}{ccc} 2 & 0 & -1\\ 1 & 0 & 0\\ 0 & 1 & 0 \end{array} \right ]}^n{ \left[ \begin{array}{ccc} s(0) & s(1) & s(2)\\ s(1) & s(0) & s(1)\\ s(-2) & s(-1) & s(0) \end{array} \right ]} s(n)s(n1)s(n2)s(n+1)s(n)s(n1)s(n+2)s(n+1)s(n)=210001100ns(0)s(1)s(2)s(1)s(0)s(1)s(2)s(1)s(0)

然后可以通过 s ( 2 ) = 2 ∗ s ( 1 ) − s ( − 1 ) , s ( 1 ) = 2 ∗ s ( 0 ) − s ( − 2 ) s(2)=2*s(1)-s(-1),s(1)=2*s(0)-s(-2) s(2)=2s(1)s(1),s(1)=2s(0)s(2)求出 s ( − 1 ) 和 s ( − 2 ) s(-1)和s(-2) s(1)s(2),虽然这样没有科学依据而正解是通过矩阵的逆,然后通过几个一元一次方程求解,但是我发现其实和这样解出的结果是一样的,那就干脆这样求好了,之前写的几道这样求也是对的

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int Mod=1e9+7;

struct Matrix{
    ll matrix[105][105];
};

int n;

Matrix mul(Matrix a,Matrix b){
    Matrix ans;
    memset(ans.matrix,0,sizeof ans.matrix);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    for(int k=1;k<=n;k++){
        ans.matrix[i][j]+=a.matrix[i][k]*b.matrix[k][j]%Mod;
        if(ans.matrix[i][j]<0) ans.matrix[i][j]=Mod+ans.matrix[i][j];  //中间结果可能为负数那么需要加上Mod
        else ans.matrix[i][j]%=Mod;
    }
    return ans;
}

Matrix qkp(Matrix mx,ll x){
    Matrix ans;
    memset(ans.matrix,0,sizeof ans.matrix);
    if(x==-1) return ans;
    for(int i=1;i<=n;i++) ans.matrix[i][i]=1;
    while(x){
        if(x&1) ans=mul(ans,mx);
        mx=mul(mx,mx);
        x>>=1;
    }
    return ans;
}


int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int t,l,r,q;
    Matrix mx,dw;
    n=3;
    mx.matrix[1][1]=2,mx.matrix[1][2]=0,mx.matrix[1][3]=-1;
    mx.matrix[2][1]=1,mx.matrix[2][2]=0,mx.matrix[2][3]=0;
    mx.matrix[3][1]=0,mx.matrix[3][2]=1,mx.matrix[3][3]=0;

    dw.matrix[1][1]=0,dw.matrix[1][2]=1,dw.matrix[1][3]=2;
    dw.matrix[2][1]=0,dw.matrix[2][2]=0,dw.matrix[2][3]=1;
    dw.matrix[3][1]=-1,dw.matrix[3][2]=0,dw.matrix[3][3]=0;

    cin>>t;
    while(t--){
        cin>>l>>r;
        Matrix res1=qkp(mx,r),res2=qkp(mx,l-1);
        res1=mul(res1,dw),res2=mul(res2,dw);
        cout<<(res1.matrix[1][1]-res2.matrix[1][1]+Mod)%Mod<<endl;
    }
    return 0;
}

相关文章:

  • 保证唯一性只能靠建唯一索引
  • HDU - 6860 Fluctuation Limit(双向贪心/思维)
  • 付出就有回报,坚持才会胜利
  • 2020牛客暑期多校第九场 E - Groundhog Chasing Death(gcd+质因数分解)
  • 高中毕业从事研发,我应该继续提高学历吗?——网上答疑(33)
  • 2020牛客暑期多校第九场 F- Groundhog Looking Dowdy(尺取)
  • HDU - 6863 Isomorphic Strings(因数分解+字符串技巧)
  • 高中毕业从事研发,我应该继续提高学历吗?——网上答疑(3
  • 2020牛客暑期多校第九场 K - The Flee Plan of Groundhog(思维+dfs)
  • iPhone人机界面指南中的意见和建议摘录
  • 2020牛客暑期多校第九场 A - Groundhog and 2-Power Representation(栈/pyhton)
  • 投稿的事情
  • 操作系统用户态和内核态之间的切换过程
  • 杜教BM(线性求递推答案)
  • FCIP vs iFCP
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 【面试系列】之二:关于js原型
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • Codepen 每日精选(2018-3-25)
  • create-react-app项目添加less配置
  • CSS实用技巧
  • Hexo+码云+git快速搭建免费的静态Blog
  • Java基本数据类型之Number
  • Java知识点总结(JavaIO-打印流)
  • Linux下的乱码问题
  • MySQL用户中的%到底包不包括localhost?
  • node学习系列之简单文件上传
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • tweak 支持第三方库
  • uva 10370 Above Average
  • yii2中session跨域名的问题
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 深入浅出webpack学习(1)--核心概念
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • Python 之网络式编程
  • 阿里云API、SDK和CLI应用实践方案
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • #pragma预处理命令
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (23)Linux的软硬连接
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (done) 两个矩阵 “相似” 是什么意思?
  • (pojstep1.1.2)2654(直叙式模拟)
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (七)Java对象在Hibernate持久化层的状态
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (三)Honghu Cloud云架构一定时调度平台
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转)linux 命令大全
  • (转)编辑寄语:因为爱心,所以美丽
  • (转)使用VMware vSphere标准交换机设置网络连接
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .cn根服务器被攻击之后