@codeforces - 717A@ Festival Organization
@description@
一个长度为 n 的 01 序列是好的,当且仅当该序列任意两个 0 不相邻。
求从 [l, r] 中选出 k 个长度相等的 01 序列的方案数。
1 ≤ k ≤ 200, 1 ≤ l ≤ r ≤ 10^18。
@solution@
定义 f[i] 表示合法 01 串数量,对最后一个是 1 还是 0 进行讨论得到 f[i] = f[i-1] + f[i-2]。
递推式有斐波那契数列形式,但注意 f[1] = 2 所以不完全是斐波那契,不过可以通过移位变成斐波那契。
以下都把它当作斐波那契数列来解决。
则问题相当于问 \(\sum_{i=l}^{r}C_{f_i}^k = \sum_{i=0}^{r}C_{f_i}^k - \sum_{i=0}^{l-1}C_{f_i}^k\)。
可以通过第一类斯特林数化成 \(\sum_{i=0}^{n}C_{f_i}^k = \frac{1}{k!}\sum_{i=0}^{n}(\sum_{j=0}^{k}S_{k}^{j}*f_{i}^j*(-1)^{k-j})\)。
问题可以等价于求 \(\sum_{i=0}^{n}f_{i}^p\)。当 p = 1, 2 的时候都可以搜到相应的式子。是否 p 增大也有相应的式子呢?
除了把递推式写成矩阵以外,斐波那契还有一个常见解决方法:通项公式。众所周知,斐波那契的通项公式可以写作 \(f[i] = a*A^i + b*B^i\)。
注意通项公式中含有 \(\sqrt{5}\),而该模数下 5 没有二次剩余。所以需要类似复数,将数存成 \((a + b*\sqrt{5})\) 的形式。
然后直接把通项公式往里面代:
\\ = \sum_{i=0}^{n}\sum_{j=0}^{p}C_p^j*(a*A^i)^j*(b*B^j)^{p-j}
\\ = \sum_{j=0}^{p}C_p^j*a^j*b^{p-j}\sum_{i=0}^{n}(A^j*B^{p-j})^i\]
等比数列求和解后面的式子即可。
最后复杂度 O(k^2logA)(还有等比数列快速幂的复杂度)。
@accepted code@
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXK = 200;
const int MOD = int(1E9) + 7;
struct mint{
int x, y;
mint(int _x=0, int _y=0) : x(_x), y(_y) {}
friend mint operator + (mint a, mint b) {
int x = (a.x + b.x >= MOD ? a.x + b.x - MOD : a.x + b.x);
int y = (a.y + b.y >= MOD ? a.y + b.y - MOD : a.y + b.y);
return mint(x, y);
}
friend mint operator - (mint a, mint b) {
int x = (a.x - b.x < 0 ? a.x - b.x + MOD : a.x - b.x);
int y = (a.y - b.y < 0 ? a.y - b.y + MOD : a.y - b.y);
return mint(x, y);
}
friend mint operator * (mint a, mint b) {
int x = (1LL*a.x*b.x + 5LL*a.y*b.y) % MOD;
int y = (1LL*a.x*b.y + 1LL*a.y*b.x) % MOD;
return mint(x, y);
}
friend mint mpow(mint a, ll k) {
mint r = 1;
while( k ) {
if( k & 1 ) r = r * a;
a = a * a;
k >>= 1;
}
return r;
}
friend mint operator / (mint a, mint b) {
mint p = a * mint(b.x, (MOD - b.y)%MOD), q = mint((1LL*b.x*b.x%MOD + MOD - 5LL*b.y*b.y%MOD)%MOD, 0);
return p * mpow(q, MOD-2);
}
}s[MAXK + 5][MAXK + 5], c[MAXK + 5][MAXK + 5];
const mint A1 = 1/mint(0,1);
const mint A2 = (1 + mint(0,1))/2;
const mint B1 = 1/mint(0,MOD-1);
const mint B2 = (1 - mint(0,1))/2;
void init() {
for(int i=0;i<=MAXK;i++) {
c[i][0] = 1;
for(int j=1;j<=i;j++)
c[i][j] = c[i-1][j] + c[i-1][j-1];
}
for(int i=0;i<=MAXK;i++)
for(int j=0;j<=i;j++)
c[i][j] = c[i][j] * mpow(A1, j) * mpow(B1, i-j);
s[0][0] = 1;
for(int i=1;i<=MAXK;i++)
for(int j=1;j<=i;j++)
s[i][j] = s[i-1][j-1] + (i-1)*s[i-1][j];
for(int i=0;i<=MAXK;i++)
for(int j=0;j<=MAXK;j++)
if( (i + j) & 1 ) s[i][j] = 0 - s[i][j];
}
int k;
mint get(mint a, ll m) {
if( a.x == 1 && a.y == 0 ) return m%MOD + 1;
else return (mpow(a, m + 1) - 1) / (a - 1);
}
mint solve(ll m) {
mint ans = 0;
for(int j=0;j<=k;j++) {
mint del = 0;
for(int p=0;p<=j;p++) {
mint tmp = mpow(A2, p) * mpow(B2, j-p);
del = del + c[j][p] * get(tmp, m);
}
ans = ans + s[k][j] * del;
}
return ans;
}
int main() {
ll l, r; init();
scanf("%d%lld%lld", &k, &l, &r), l += 2, r += 2;
mint p = 1; for(int i=1;i<=k;i++) p = p*i;
printf("%d\n", ((solve(r) - solve(l-1))/p).x);
}
@details@
注意等比数列特判公比为 1 !!!(老是记不住)
貌似是 BJOI2019 的勘破神机?
@codeforces - 717A@ Festival Organization的更多相关文章
- CF 717A Festival Organization——斯特林数+递推求通项+扩域
题目:http://codeforces.com/contest/717/problem/A 是 BJOI2019 勘破神机 的弱化版. 令 \( g[i] \) 表示长为 i .以 1 结尾的方案数 ...
- CF717 Festival Organization
\(CF717\ Festival\ Organization\) Description 一个合法的串定义为:长度在 \([l,r]\) 之间,且只含 \(0,1\),并且不存在连续 \(2\) 个 ...
- CF717A Festival Organization(第一类斯特林数,斐波那契数列)
题目大意:求 $\sum\limits_{n=l}^{r}\dbinom{f_n}{k}\bmod 10^9+7$.其中 $f_n$ 是长度为 $n$ 的 $01$ 序列中,没有连续两个或超过两个 $ ...
- Codeforces Round #127 (Div. 1) E. Thoroughly Bureaucratic Organization 二分 数学
E. Thoroughly Bureaucratic Organization 题目连接: http://www.codeforces.com/contest/201/problem/E Descri ...
- codeforces 340C Tourist Problem
link:http://codeforces.com/problemset/problem/340/C 开始一点也没思路,赛后看别人写的代码那么短,可是不知道怎么推出来的啊! 后来明白了. 首先考虑第 ...
- codeforces magic five --快速幂模
题目链接:http://codeforces.com/contest/327/problem/C 首先先算出一个周期里面的值,保存在ans里面,就是平常的快速幂模m做法. 然后要计算一个公式,比如有k ...
- Codeforces Round #219 (Div. 2) E. Watching Fireworks is Fun
http://codeforces.com/contest/373/problem/E E. Watching Fireworks is Fun time limit per test 4 secon ...
- python爬虫学习(5) —— 扒一下codeforces题面
上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
随机推荐
- SQLServer-SQLServer2017:SQLServer2017
ylbtech-SQLServer-SQLServer2017:SQLServer2017 微软推出了首个公共预览版本,并持续带来更新和改进.而今天,微软同时向 Windows.Linux.macOS ...
- Android App的设计架构:MVC,MVP,MVVM与架构AAAAA
1. 架构设计的目的1.1 通过设计使程序模块化,做到模块内部的高聚合和模块之间的低耦合.1.2 这样做的好处是使得程序在开发的过程中,开发人员只需要专注于一点,提高程序开发的效率,并且更容易进行后续 ...
- hibernate 注释多表 级联操作
一对多模型(单向) 说明: 一个客户对应多个地址,通过客户可以获得该客户的多个地址的信息.客户和地址是一对多的关系,并且客户与地址是单向关联的关系. 映射策略 # 外键关联:两个表的关系定义在一个表中 ...
- Python模块安装方式
一.方法1: 单文件模块直接把文件拷贝到 $python_dir/lib/python3.4/site-packages/ 二.方法2: 多文件模块,带setup.py 下载模块包,进行解压,进入模块 ...
- consul原理
阅读目录 一.使用Consul做服务发现的若干姿势 1.https://www.cnblogs.com/bossma/p/9756809.html 阅读目录 启动第1个Server节点,集群要求要有3 ...
- AC自动机(模板) LUOGU P3808
传送门 解题思路 AC自动机,是解决多模匹配问题的算法,是字典树与kmp结合的算法,可以解决许多子串在文本串中出现的次数等信息.关键是实现一个fail指针,是指向更靠上的前缀相同字母,从而可以实现在文 ...
- 搭建php虚拟环境
参考网址: http://my.oschina.net/u/998304/blog/501363?p={{totalPage}} Box镜像列表: http://www.vagrantbox.es/ ...
- 傳説中的 jsonp
jsonp的由來 1 . 網頁上的東西衹要跨域了就不能傳送或者接受數據了.不管是什麽衹要是跨域.Ajax直接请求普通文件存在跨域无权限访问的问题, 2 . 但是src這個東西比較厲害了,請求哪裏都可以 ...
- 八大 IoT 安全关键技术解析
IoT 设备的增长也伴随着网络攻击的风险的增长,因此在设计产品时就必须考虑到系统的安全. 高德纳咨询公司最近的报告预测,到 2020 年,全世界将有 200.4 亿的物联网设备相互连接,且平均每天约还 ...
- 想真正了解JAVA设计模式看着一篇就够了。 详解+代码实例
Java 设计模式 设计模式是对大家实际工作中写的各种代码进行高层次抽象的总结 设计模式分为 23 种经典的模式,根据用途我们又可以分为三大类.分别是创建型模式.结构型模式和行为型模式 列举几种设 ...