解析

非常妙的一个题,感受到了斐波拉契优美的归纳性质。

首先,不难发现只要两个1*1的位置固定,中间的摆法就固定了,而两边的方案都是经典的斐波拉契数列(设为 fif_ifi​)。
那么枚举中间的间隔再枚举左边的长度,就有:
ans=2∑i=3n∑j=0n−ifjfn−i−jans=2\sum_{i=3}^n\sum_{j=0}^{n-i}f_jf_{n-i-j}ans=2i=3∑n​j=0∑n−i​fj​fn−i−j​
乘二是因为对于一种间隔,中间的砖有两种摆法。
转换一下求和顺序:
ans=2∑i=0n−3fi∑j=0n−3−ifjans=2\sum_{i=0}^{n-3}f_i\sum_{j=0}^{n-3-i}f_jans=2i=0∑n−3​fi​j=0∑n−3−i​fj​
然后有一个斐波拉契的经典结论(然而我并不会):
∑i=0nfi=fn+2−1\sum_{i=0}^nf_i=f_{n+2}-1i=0∑n​fi​=fn+2​−1
证明直接归纳即可。
所以原式就等于:
2∑i=0n−3fi(fn−1−i−1)=2(∑i=0n−3fifn−1−i−(fn−1−1))=2(∑i=0n−1fifn−1−i+1−2fn−1−fn−2)2\sum_{i=0}^{n-3}f_i(f_{n-1-i}-1)=2(\sum_{i=0}^{n-3}f_if_{n-1-i}-(f_{n-1}-1))=2(\sum_{i=0}^{n-1}f_if_{n-1-i}+1-2f_{n-1}-f_{n-2})2i=0∑n−3​fi​(fn−1−i​−1)=2(i=0∑n−3​fi​fn−1−i​−(fn−1​−1))=2(i=0∑n−1​fi​fn−1−i​+1−2fn−1​−fn−2​)
设 sn=∑i=0nfifn−is_n=\sum_{i=0}^nf_if_{n-i}sn​=∑i=0n​fi​fn−i​,答案就是 2(s(n−1)+1−2fn−1−fn−2)2(s(n-1)+1-2f_{n-1}-f_{n-2})2(s(n−1)+1−2fn−1​−fn−2​)。
再看看 sns_nsn​ 等于什么:
sn=∑i=0nfifn−i=fn+fn−1+∑i=0n−2fifn−is_n=\sum_{i=0}^nf_if_{n-i}=f_n+f_{n-1}+\sum_{i=0}^{n-2}f_if_{n-i}sn​=i=0∑n​fi​fn−i​=fn​+fn−1​+i=0∑n−2​fi​fn−i​
=fn+fn−1+∑i=0n−2fi(fn−i−1+fn−i−2)=fn+sn−1+sn−2=f_n+f_{n-1}+\sum_{i=0}^{n-2}f_i(f_{n-i-1}+f_{n-i-2})=f_n+s_{n-1}+s_{n-2}=fn​+fn−1​+i=0∑n−2​fi​(fn−i−1​+fn−i−2​)=fn​+sn−1​+sn−2​
(第二步可以拆 fn−if_{n-i}fn−i​ 是因为此时有 n−i>=2n-i>=2n−i>=2)
这样,我们就得到了 sss 的递推式,也非常优美。
把 f,sf,sf,s 拼在一起构造出转移矩阵,快速幂加速即可。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
using namespace std;const int N=4e5+100;
const int mod=1e9+7;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
int n,m;struct matrix{int x,y;ll a[5][5];matrix(int X,int Y){x=X;y=Y;memset(a,0,sizeof(a));}
};
matrix operator * (const matrix &u,const matrix &v){matrix res(u.x,v.y);for(int k=1;k<=u.y;k++){for(int i=1;i<=u.x;i++){ll tmp=u.a[i][k];for(int j=1;j<=v.y;j++){(res.a[i][j]+=tmp*v.a[k][j])%=mod;}}}return res;
}
int trans[5][5]={{},{0,0,1,0,1},{0,1,1,0,1},{0,0,0,0,1},{0,0,0,1,1},
};
matrix I(4,4),o(4,4),ori(1,4);
matrix ksm(matrix x,int k){matrix res=I;while(k){if(k&1) res=res*x;x=x*x;k>>=1;}return res;
}signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifint T=read();for(int i=1;i<=4;i++) I.a[i][i]=1;for(int i=1;i<=4;i++){for(int j=1;j<=4;j++) o.a[i][j]=trans[i][j];}ori.a[1][1]=1;ori.a[1][2]=1;ori.a[1][3]=1;ori.a[1][4]=2;while(T--){n=read();if(n<=1) puts("0");else{matrix res=ori*ksm(o,n-2);//printf("%lld %lld %lld %lld\n",res.a[1][1],res.a[1][2],res.a[1][3],res.a[1][4]);printf("%lld\n",(res.a[1][4]+1-(2*res.a[1][2]+res.a[1][1])%mod+mod)*2%mod);}}return 0;
}
/*
1
5 0 0 5.001 5.002
*/

P5303 [GXOI/GZOI2019]逼死强迫症(斐波拉契、矩阵乘法)相关推荐

  1. 「GXOI / GZOI2019」逼死强迫症——斐波那契+矩阵快速幂

    题目 [题目描述] ITX351 要铺一条 $2 \times N$ 的路,为此他购买了 $N$ 块 $2 \times 1$ 的方砖.可是其中一块砖在运送的过程中从中间裂开了,变成了两块 $1 \t ...

  2. P5303 [GXOI/GZOI2019]逼死强迫症 题解

    P5303 [GXOI/GZOI2019]逼死强迫症 P5303 [GXOI/GZOI2019]逼死强迫症 说实在的这题不难,但是我推 Dp\tt DpDp 的时候却只和正解相差一点,最后还是看了题解 ...

  3. 【题解】Luogu-P5303 [GXOI/GZOI2019]逼死强迫症

    P5303 [GXOI/GZOI2019]逼死强迫症 Preface 矩阵题的登峰造极之作. Description 有 TTT 组数据. 对于每组数据,给定正整数 NNN,请求出用 (N−1)(N- ...

  4. 【详●析】[GXOI/GZOI2019]逼死强迫症

    [详●析][GXOI/GZOI2019]逼死强迫症 脑子不够用了... [题目大意] 在\(2\times N\)的方格中用\(N-1\)块\(2\times 1\)的方砖和\(2\)块\(1\tim ...

  5. 冒泡排序,斐波拉契迭代、生成器

    冒泡排序: l=[1,3,0,100,1000,8,2,9,5,11,8]def maopao(l):for i in range(len(l)-1):if l[i+1] < l[i]:a= l ...

  6. [python]练习之递归和循环实现斐波拉契数列

    1 # 程序功能:用递归和循环实现斐波拉契数列 2 # 0 1 1 2 3 5 8 13 21 34 3 4 def digui_fibo(number): 5 if number == 1: 6 r ...

  7. 动态规划学习之三种方法解决斐波拉契数

    斐波拉契数是一个很经典的问题,也会很多公司面试的考题,每个学习计算机的同学都会接触这个问题,尤其是在学习递归的时候,利用递归来解决斐波拉契数是很多教材采用的一个例子,所以很多同学一想到斐波拉契马上就会 ...

  8. 函数-生成器之斐波拉契数列

    斐波拉契数列:除第一个和第二个数外,任意一个数都可以由前两个数相加而来. 无法用生成式,但可由函数生成. 函数生成斐波拉契数列数列: def fib(max):n,a,b=0,0,1while n & ...

  9. C语言数据结构----递归的应用(斐波拉契数列、汉诺塔、strlen的递归算法)

    本节主要说了递归的设计和算法实现,以及递归的基本例程斐波拉契数列.strlen的递归解法.汉诺塔和全排列递归算法. 一.递归的设计和实现 1.递归从实质上是一种数学的解决问题的思维,是一种分而治之的思 ...

最新文章

  1. 对象检测和浏览器检测
  2. Linux下的crontab定时执行任务命令详解
  3. asprise java_使用asprise进行图片验证码识别
  4. Important table for Fiori launchpad Designer and configuration
  5. CommonResult响应工具类封装
  6. C++(17)--详解const
  7. php权限设置,php设置权限的方法
  8. Qt4_子类化QTableWidgetItem
  9. 解决apache启动错误httpd:Could not reliably determine...
  10. python编程的50种基础算法_Python入门教程:几种常见的Python算法实现
  11. DSP到底是个什么鬼?看完你就懂了
  12. LR11中将IE9降级为IE8
  13. qss样式表之QComboBox
  14. 爬网易云音乐动态的坑
  15. pdm怎么导入oracle,PowerDesigner导入导出PDM和rtf文件
  16. ACM公约数和公倍数
  17. 浅析3D音效的技术和发展
  18. bzoj3894 文理分科 最小割
  19. BigDecimal.ROUND_的各种用法
  20. Python版经典小游戏愤怒的小鸟源代码,基于pygame+pymunk

热门文章

  1. 数学家破解婚恋网站配对程序,90天找到灵魂伴侣
  2. mysql判断表存在的sql语句_SQL 语句判断已知表是否存在_MySQL
  3. java对jar包的复制_Java安全之jar包调试技巧
  4. php正则匹配标点符号,php 正则匹配包含字母、数字以及下划线,且至少包含2种...
  5. git maven 一键部署_Jenkins Git Maven搭建自动化部署项目环境 邮件通知
  6. cv2.imread读取图像结果none_python cv2.imread 读取中文路径的图片返回为None的问题
  7. Factory Method(工厂方法)--对象创建型模式
  8. hash table(全域散列法实现的哈希表)
  9. 辅助类BinaryTreeNodeLeftChildRightSibling(左孩子右兄弟,二叉树结点)
  10. 数据结构与算法--这个需求很简单怎么实现我不管(发散思维)