【做题】SRM701 Div1 Hard - FibonacciStringSum——数学和式&矩阵快速幂
原文链接 https://www.cnblogs.com/cly-none/p/SRM701Div1C.html
题意:定义"Fibonacci string"为没有连续1的01串。现在,给出\(a,b\),定义一个"Fibonacci string"的权值为\(x^a y^b\),其中\(x\)为0的个数,\(y\)为1的个数。
要求对所有长度为\(n\)的"Fibonacci string"的权值求和,对\(10^9 + 7\)取模。
\(n \leq 10^9, \ a, b \leq 25\)
显然第一反应就是矩阵存下所有\((a,b)\)做快速幂。然而,这样的话矩阵的边长是\(O(a^2)\)的,不能通过本题。
考虑最终答案的式子:
\]
我们尝试化简:
& \sum_{k=0}^n {n-k+1 \choose k} k^b (n-k)^a \\
= & \sum_{k=0}^n \sum_{j=0}^a {n-k+1 \choose k} k^b {a\choose j} n^{a-j} (-k)^j \\
= & \sum_{j=0}^a {a \choose j} (-1)^j \sum_{k=0}^n {n-k+1 \choose k}k^{b+j}
\end{aligned}
\]
注意到后面的\(\sum_{k=0}^n {n-k+1 \choose k} k^{b+j}\)就是当\(a' = 0, \ b' = b+j\)时,所有长度为\(n\)的"Fibonacci string"的权值和。这时,我们再建矩阵,边长就只有\(O(a)\)了。最后\(O(a)\)枚举\(j\)就能计算出答案。
时间复杂度\(O(a^3 \log n)\)。
#include <bits/stdc++.h>
using namespace std;
const int MOD = (int)(1e9 + 7), N = 110;
struct matrix {
int n,m,mat[N][N];
matrix(int n=0,int m=0): n(n), m(m) {
memset(mat,0,sizeof mat);
}
matrix operator * (const matrix& a) const {
assert(m == a.n);
matrix ret = matrix(n, a.m);
for (int k = 0 ; k < m ; ++ k)
for (int i = 0 ; i < n ; ++ i)
for (int j = 0 ; j < a.m ; ++ j)
(ret.mat[i][j] += 1ll * mat[i][k] * a.mat[k][j] % MOD) %= MOD;
return ret;
}
};
matrix power(matrix a,int b) {
assert(a.n == a.m);
matrix ret = matrix(a.n, a.m);
for (int k = 0 ; k < a.n ; ++ k)
ret.mat[k][k] = 1;
while (b) {
if (b&1) ret = ret * a;
a = a * a;
b >>= 1;
}
return ret;
}
int power(int a,int b) {
int ret = 1;
while (b) {
if (b&1) ret = 1ll * ret * a % MOD;
a = 1ll * a * a % MOD;
b >>= 1;
}
return ret;
}
class FibonacciStringSum {
public:
int get( int n, int a, int b ) ;
};
int val[N],cmb[N][N];
int FibonacciStringSum::get(int n, int a, int b) {
memset(cmb,0,sizeof cmb);
for (int i = 0 ; i <= a + b ; ++ i)
cmb[i][0] = 1;
for (int i = 1 ; i <= a + b ; ++ i)
for (int j = 1 ; j <= i ; ++ j)
cmb[i][j] = (cmb[i-1][j] + cmb[i-1][j-1]) % MOD;
matrix sta = matrix(1, 2 * (a + b + 1));
matrix tran = matrix(2 * (a + b + 1), 2 * (a + b + 1));
sta.mat[0][0] = 1;
for (int i = 0 ; i <= a + b ; ++ i) {
tran.mat[i][i] = 1;
tran.mat[i + a + b + 1][i] = 1;
for (int j = 0 ; j <= i ; ++ j)
tran.mat[j][a + b + 1 + i] += cmb[i][j];
}
tran = power(tran, n);
sta = sta * tran;
for (int i = 0 ; i <= a + b ; ++ i)
val[i] = (sta.mat[0][i] + sta.mat[0][i + a + b + 1]) % MOD;
int ans = 0;
for (int i = 0, t = 1 ; i <= a ; ++ i, t = -t)
(ans += 1ll * t * cmb[a][i] * power(n, a - i) % MOD * val[b + i] % MOD) %= MOD;
ans = (ans % MOD + MOD) % MOD;
return ans;
}
小结:这个问题的特殊之处在于,既可以直接矩阵快速幂,也可以写成数学和式。然而,二者都不能直接解决这个问题。把两种方法相结合一直是常用的技巧(如分块),在这里也启示我们对于一个问题不能死板地但从一个方向来思考。
【做题】SRM701 Div1 Hard - FibonacciStringSum——数学和式&矩阵快速幂的更多相关文章
- [ An Ac a Day ^_^ ] hdu 4565 数学推导+矩阵快速幂
从今天开始就有各站网络赛了 今天是ccpc全国赛的网络赛 希望一切顺利 可以去一次吉大 希望还能去一次大连 题意: 很明确是让你求Sn=[a+sqrt(b)^n]%m 思路: 一开始以为是水题 暴力了 ...
- 2018.09.26 bzoj5221: [Lydsy2017省队十连测]偏题(数学推导+矩阵快速幂)
传送门 由于没有考虑n<=1的情况T了很久啊. 这题很有意思啊. 考试的时候根本不会,骗了30分走人. 实际上变一个形就可以了. 推导过程有点繁杂. 直接粘题解上的请谅解. 不得不说这个推导很妙 ...
- BZOJ 2326: [HNOI2011]数学作业( 矩阵快速幂 )
BZOJ先剧透了是矩阵乘法...这道题显然可以f(x) = f(x-1)*10t+x ,其中t表示x有多少位. 这个递推式可以变成这样的矩阵...(不会用公式编辑器...), 我们把位数相同的一起处理 ...
- [HNOI2011]数学作业 矩阵快速幂 BZOJ 2326
题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 NNN 和 MMM ,要求计算Concatenate(1..N) Concatenate (1 .. N) ...
- 51nod 1242 斐波那契数列的第N项——数学、矩阵快速幂
普通算法肯定T了,所以怎么算呢?和矩阵有啥关系呢? 打数学符号太费时,就手写了: 所以求Fib(n)就是求矩阵 | 1 1 |n-1 第一行第一列的元素. | 1 0 | 其实学过线代 ...
- Codeforces Round #362(Div1) D Legen...(AC自动机+矩阵快速幂)
题目大意: 给定一些开心串,每个串有一个开心值,构造一个串,每包含一次开心串就会获得一个开心值,求最大获得多少开心值. 题解: 首先先建立AC自动机.(建立fail指针的时候,对val要进行累加) 然 ...
- 刷题总结—— Scout YYF I(poj3744 矩阵快速幂+概率dp)
题目: Description YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate int ...
- hdu 5171 GTY's birthday gift(数学,矩阵快速幂)
题意: 开始时集合中有n个数. 现在要进行k次操作. 每次操作:从集合中挑最大的两个数a,b进行相加,得到的数添加进集合中. 以此反复k次. 问最后集合中所有数的和是多少. (2≤n≤100000,1 ...
- (中等) CF 576D Flights for Regular Customers (#319 Div1 D题),矩阵快速幂。
In the country there are exactly n cities numbered with positive integers from 1 to n. In each city ...
随机推荐
- 2018-2019-2 网络对抗技术 20165225 Exp6 信息搜集与漏洞扫描
2018-2019-2 网络对抗技术 20165225 Exp6 信息搜集与漏洞扫描 实践内容 (1)各种搜索技巧的应用 (2)DNS IP注册信息的查询 (3)基本的扫描技术:主机发现.端口扫描.O ...
- 初入 vue
基于 vue.js 的前端开发环境,用于前后端分离后的单页应用开发. 搭建 vue 项目 按官方指引,使用 vue-cli 搭建 vue 的项目. # 安装依赖库,建议指定 vue 和 element ...
- ADB——查看手机设备信息
查看设备信息 查看手机型号 adb shell getprop ro.product.model 查看电池状况 adb shell dumpsys battery ''' Current Batter ...
- 2019-04-15 Python之利用matplotlib和numpy的简单绘图
环境:win10家庭版, Anocada的 Spyder 一.简单使用 使用函数 plt.polt(x,y,label,color,width) 根据x,y 数组 绘制直,曲线 import nump ...
- MIPI-Layout说明(转载)
转载于:http://www.ccm99.com/thread-3713-1-1.html 前言:随着新的总线协议不断提高信号速率,如今的PCB 设计人员需要充分理解高速布线的要求并控制PCB 走线的 ...
- 浅析对spring中IOC的理解
学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...
- meta 标签汇总
HTML 里 meta常用标签: " class="mathcode" src="https://private.codecogs.com/gif.latex? ...
- vs2017 git凭证问题
安装完tfs2017(自带git)后,连接git代码服务器,报authorication错误.这是vs2017的bug.尝试了许多种方案后,最简单的干脆手动添加如下3个凭证.一定要核对好地址中的. ...
- Unity如何退出游戏
使用 Application.Quit(),但在 editor 模式下使用 Application.Quit()是没用的,要用 EditorApplication.isPlaying = false. ...
- JavaScript之基础语法整理
1.数据类型(number,boolean,string,null,undefined,symbol,object) es是动态语言,弱类型语言,虽然先声明了变量,但是变量可以重新赋值任意类型 弱类型 ...