CF717A Festival Organization(第一类斯特林数,斐波那契数列)
题目大意:求 $\sum\limits_{n=l}^{r}\dbinom{f_n}{k}\bmod 10^9+7$。其中 $f_n$ 是长度为 $n$ 的 $01$ 序列中,没有连续两个或超过两个 $0$ 的个数。
$1\le k\le 200,1\le l\le r\le 10^{18}$。
先考虑如何求 $f_n$。
令 $g[i][j]$ 表示长度为 $i$,结尾是 $j$ 的序列个数。
$$g[i][0]=g[i-1][1]$$
$$g[i][1]=g[i-1][0]+g[i-1][1]$$
将第一个式子代入第二个式子有 $g[i][1]=g[i-2][1]+g[i-1][1]$。
手玩发现 $g[1][1]=1,g[2][1]=2$。那么有 $g[i][1]=fib_{i+1}$。($fib$ 是斐波那契数列)
要求 $g[i][0]+g[i][1]=g[i-1][1]+g[i][1]=g[i+1][1]=fib_{i+2}$。
那么式子就是 $\sum\limits_{n=l+2}^{r+2}\dbinom{fib_n}{k}$。(为方便 $l+=2,r+=2$,下文假设是 $l$ 到 $r$)
$$\sum\limits_{n=l}^r\dbinom{fib_n}{k}$$
$$\dfrac{1}{k!}\sum\limits_{n=l}^rfib_n^{\underline{k}}$$
$$\dfrac{1}{k!}\sum\limits_{n=l}^r\sum\limits_{i=0}^k(-1)^{k-i}\begin{bmatrix}k\\i\end{bmatrix}fib_n^i$$
$$\dfrac{1}{k!}\sum\limits_{i=0}^k(-1)^{k-i}\begin{bmatrix}k\\i\end{bmatrix}\sum\limits_{n=l}^rfib_n^i$$
前面可以随便枚举,然而斐波那契 $k$ 次方前缀和这东西怎么搞?
这时就要用上大名鼎鼎的通项公式:(没记住的也可以现场用特征方程推)
$$fib_n=\dfrac{\sqrt{5}}{5}(\dfrac{1+\sqrt{5}}{2})^n-\dfrac{\sqrt{5}}{5}(\dfrac{1-\sqrt{5}}{2})^n$$
令 $a=\dfrac{\sqrt{5}}{5},b=-\dfrac{\sqrt{5}}{5},x=\dfrac{1+\sqrt{5}}{2},y=\dfrac{1-\sqrt{5}}{2}$,那么 $fib_n=ax^n+by^n$。
$$\dfrac{1}{k!}\sum\limits_{i=0}^k(-1)^{k-i}\begin{bmatrix}k\\i\end{bmatrix}\sum\limits_{n=l}^r(ax^n+by^n)^i$$
$$\dfrac{1}{k!}\sum\limits_{i=0}^k(-1)^{k-i}\begin{bmatrix}k\\i\end{bmatrix}\sum\limits_{n=l}^r\sum\limits_{j=0}^i\dbinom{i}{j}(ax^n)^j(by^n)^{i-j}$$
$$\dfrac{1}{k!}\sum\limits_{i=0}^k(-1)^{k-i}\begin{bmatrix}k\\i\end{bmatrix}\sum\limits_{n=l}^r\sum\limits_{j=0}^i\dbinom{i}{j}(a^jb^{i-j})(x^jy^{i-j})^n$$
$$\dfrac{1}{k!}\sum\limits_{i=0}^k(-1)^{k-i}\begin{bmatrix}k\\i\end{bmatrix}\sum\limits_{j=0}^i\dbinom{i}{j}(a^jb^{i-j})\sum\limits_{n=l}^r(x^jy^{i-j})^n$$
此时 $i$ 和 $j$ 可以 $O(k^2)$ 枚举,而 $n$ 那里是个等差数列,总复杂度 $O(k^2\log r)$。(可能要预处理出所有斯特林数和组合数才能做到这个复杂度)
但是有个严重的问题:$\sqrt{5}$ 在模 $10^9+7$ 意义下不存在。
那么就要用到一个骚操作:扩系。
令 $(a,b)=a+b\sqrt{5}$,那么上文中的四个常数 $a=(0,5^{-1}),b=(0,-5^{-1}),x=(2^{-1},2^{-1}),y=(2^{-1},-2^{-1})$。
那么进行加减乘除就简单了:
$$(a,b)\pm(c,d)=(a\pm c,b\pm d)$$
$$(a,b)\times(c,d)=(ac+5bd,ad+bc)$$
$$\dfrac{1}{(a,b)}=(\dfrac{a}{a^2-5b^2},\dfrac{-b}{a^2-5b^2})$$
因为式子没推错(只能这么想了啊),最后求出的一定是整数。
那么就做完了。
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int maxn=,mod=,inv2=,inv5=;
- #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
- #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
- #define MEM(x,v) memset(x,v,sizeof(x))
- inline ll read(){
- char ch=getchar();ll x=,f=;
- while(ch<'' || ch>'') f|=ch=='-',ch=getchar();
- while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
- return f?-x:x;
- }
- int k,fac[maxn],invfac[maxn],ans,S[maxn][maxn],C[maxn][maxn];
- ll l,r;
- inline int add(int x,int y){return x+y<mod?x+y:x+y-mod;}
- inline int sub(int x,int y){return x<y?x-y+mod:x-y;}
- inline int mul(int x,int y){return 1ll*x*y%mod;}
- inline int qpow(int a,ll b){
- int ans=;
- for(;b;b>>=,a=mul(a,a)) if(b&) ans=mul(ans,a);
- return ans;
- }
- struct comp{
- int x,y;
- comp(const int xx=,const int yy=):x(xx),y(yy){}
- inline comp operator+(const comp &c)const{return comp(add(x,c.x),add(y,c.y));}
- inline comp operator-(const comp &c)const{return comp(sub(x,c.x),sub(y,c.y));}
- inline comp operator*(const comp &c)const{return comp(add(mul(x,c.x),mul(,mul(y,c.y))),add(mul(x,c.y),mul(y,c.x)));}
- inline comp inv()const{
- comp ans(x,y?mod-y:);
- int dn=qpow(sub(mul(x,x),mul(,mul(y,y))),mod-);
- return ans*dn;
- }
- inline comp operator/(const comp &c)const{return *this*c.inv();}
- inline bool operator==(const comp &c)const{return x==c.x && y==c.y;}
- }a(,inv5),b(,mod-inv5),x(inv2,inv2),y(inv2,mod-inv2);
- inline comp cqpow(comp a,ll b){
- comp ans(,);
- for(;b;b>>=,a=a*a) if(b&) ans=ans*a;
- return ans;
- }
- comp calc(comp x,ll l,ll r){
- if(x==) return (r-l+)%mod;
- return (cqpow(x,r+)-cqpow(x,l))/(x-);
- }
- int main(){
- k=read();l=read();r=read();
- FOR(i,,k) C[i][]=C[i][i]=;
- FOR(i,,k) FOR(j,,i-) C[i][j]=add(C[i-][j],C[i-][j-]);
- S[][]=;
- FOR(i,,k) FOR(j,,i) S[i][j]=add(mul(i-,S[i-][j]),S[i-][j-]);
- fac[]=;
- FOR(i,,k) fac[i]=mul(fac[i-],i);
- invfac[k]=qpow(fac[k],mod-);
- FOR(i,,k){
- int s=;
- FOR(j,,i){
- comp tmp1=cqpow(a,j)*cqpow(b,i-j),tmp2=cqpow(x,j)*cqpow(y,i-j);
- s=add(s,mul(C[i][j],(tmp1*calc(tmp2,l+,r+)).x));
- }
- s=mul(s,S[k][i]);
- if((k-i)&) ans=sub(ans,s);
- else ans=add(ans,s);
- }
- printf("%d\n",mul(ans,invfac[k]));
- }
CF717A Festival Organization(第一类斯特林数,斐波那契数列)的更多相关文章
- codeforce 227E 矩阵快速幂求斐波那契+N个连续数求最大公约数+斐波那契数列的性质
E. Anniversary time limit per test2 seconds memory limit per test256 megabytes inputstandard input o ...
- 斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)
对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - ) + F(n - ),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围 ...
- 剑指Offer面试题:8.斐波那契数列
一.题目:斐波那契数列 题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项.斐波那契数列的定义如下: 二.效率很低的解法 很多C/C++/C#/Java语言教科书在讲述递归函数的时 ...
- ACM2 斐波那契数列
描述 在数学上,斐波那契数列(Fibonacci Sequence),是以递归的方法来定义: F0 = 0 F1 = 1 Fn = Fn - 1 + Fn - 2 用文字来说,就是斐波那契数列由0和1 ...
- 关于斐波拉契数列(Fibonacci)
斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10 ...
- [NOIP1997] P2626 斐波那契数列(升级版)
题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数). 题目描述 ...
- hdu 2044:一只小蜜蜂...(水题,斐波那契数列)
一只小蜜蜂... Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Submission(s): Accepte ...
- 【Java】斐波那契数列(Fibonacci Sequence、兔子数列)的3种计算方法(递归实现、递归值缓存实现、循环实现、尾递归实现)
斐波那契数列:0.1.1.2.3.5.8.13………… 他的规律是,第一项是0,第二项是1,第三项开始(含第三项)等于前两项之和. > 递归实现 看到这个规则,第一个想起当然是递归算法去实现了, ...
- Python(迭代器 生成器 装饰器 递归 斐波那契数列)
1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优 ...
随机推荐
- Vue.js 源码分析(二十七) 高级应用 异步组件 详解
当我们的项目足够大,使用的组件就会很多,此时如果一次性加载所有的组件是比较花费时间的.一开始就把所有的组件都加载是没必要的一笔开销,此时可以用异步组件来优化一下. 异步组件简单的说就是只有等到在页面里 ...
- Eureka配置
介绍 SpringCloud是一个完整的微服务治理框架,包括服务发现和注册,服务网关,熔断,限流,负载均衡和链路跟踪等组件. SpringCloud-Eureka主要提供服务注册和发现功能.本文提供了 ...
- 一个动态构建 LambdaExpression Tree 的示例
直接贴代码了: public class ExpressionTreeBuildingSampleTwo : Sample { public override string Name { get; } ...
- Kubernetes 中的服务发现与负载均衡
原文:https://www.infoq.cn/article/rEzx9X598W60svbli9aK (本文转载自阿里巴巴云原生微信公众号(ID:Alicloudnative)) 一.需求来源 为 ...
- git 使用 tortoisegit 解冲突
git 解冲突需要注意的问题 弄清除冲突双向的修改意图,并在解决冲突时,同时处理两边的意图. 举例说明 A.txt 文件, 在 master 分支上,有一行文字(代码)是这样: 这是一段在 maste ...
- c# 值类型和引用类型 笔记
参考以下博文,我这里只是笔记一下,原文会更加详细 c#基础系列1---深入理解值类型和引用类型 堆栈和托管堆c# 值类型和引用类型 红色表示——“这啥?”(真实1个问题引出3个问题) CLR支持的两种 ...
- Python基础23(习惯)
自己写的大段代码,注释分为两种: 一种 # 顶格写,为后注释," Ctrl+/ " 一种为边写边注释
- apache-tomcat-7.0.94在Windows上启动时,控制台黑窗口出现乱码解决
一.问题 二.解决 原因是tomcat日志编码的配置问题. 打开tomcat/conf/logging.properties配置文件. 把编码注释掉或者改为gbk就可以了. 参考:https://bl ...
- 开发技术--浅谈python数据类型
开发|浅谈python数据类型 在回顾Python基础的时候,遇到最大的问题就是内容很多,而我的目的是回顾自己之前学习的内容,进行相应的总结,所以我就不玩基础了,很多在我实际生活中使用的东西,我会在文 ...
- Ext.id
Ext.id([el,prefix]) el: 是要添加id的元素,值可以为元素id值.HTMLElement对象或Element对象:prefix:是自定义的id前缀字符串 传入el:如果el已经有 ...