【做题】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 ...
随机推荐
- windows android ndk的某些编译工具报错乱码0x5 或拒绝访问05
在IDEA或者AndroidStudio的快捷方式上右键属性 > 兼容性 > 以管理员身份运行 解决问题.
- Python中的锁
一.全局解释器锁(GIL) 1.什么是全局解释器锁 在同一个进程中只要有一个线程获取了全局解释器(cpu)的使用权限,那么其他的线程就必须等待该线程的全局解释器(cpu)使用权消失后才能使用全局解释器 ...
- 一次 Spark SQL 性能提升10倍的经历(转载)
1. 遇到了啥问题 是酱紫的,简单来说:并发执行 spark job 的时候,并发的提速很不明显. 嗯,且听我慢慢道来,啰嗦点说,类似于我们内部有一个系统给分析师用,他们写一些 sql,在我们的 sp ...
- 【LeetCode每天一题】Simplify Path(简化路径)
Given an absolute path for a file (Unix-style), simplify it. Or in other words, convert it to the ca ...
- Postman代码测试工具如何用?
1. 1)get请求,参数为map时, postman的传参 2)参数为基本数据类型的参数时 postman传参: 3)当参数在接口中动态获取时 postman传参: 2. 1)post请求,参数 ...
- IMU 标定 | 工业界和学术界有什么不同?
点击"计算机视觉life"关注,置顶更快接收消息! 由于格式问题最好在公众号上观看<IMU 标定-工业界和学术界有什么不同?> 本文主要介绍了IMU基本结构原理和误差的 ...
- upCode
更新源码 Sub main() Dim str As String str = "这是测试的字符串对话框" MsgBox str Sheets(1).Select End Sub
- nodejs:导出Excel和解析导入的Excel
用的是koa2框架,但好好处理一下,用express框架也是可以的.导出的Excel是xlsx的格式,解析导入Excel的有xlsx和csv格式.通常导入Excel是要上传的,然后获取文件的路径,这里 ...
- Bioinfo online workshop
http://icb.med.cornell.edu/index.html%3Fpage_id=2068.html 1. Datacamp https://www.datacamp.com/cours ...
- 多线程之CEvent
最近工作中要维护一个windows模块,用到了mfc中的CEvent类.这算是很久很久以前的老朋友了吧,估计和我超过10年没见过面了,不过工作就是工作,技术上来不得半点含糊,所以还是重新认识一下这位老 ...