原文链接 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
\]

我们尝试化简:

\[\begin{aligned}
& \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——数学和式&矩阵快速幂的更多相关文章

  1. [ An Ac a Day ^_^ ] hdu 4565 数学推导+矩阵快速幂

    从今天开始就有各站网络赛了 今天是ccpc全国赛的网络赛 希望一切顺利 可以去一次吉大 希望还能去一次大连 题意: 很明确是让你求Sn=[a+sqrt(b)^n]%m 思路: 一开始以为是水题 暴力了 ...

  2. 2018.09.26 bzoj5221: [Lydsy2017省队十连测]偏题(数学推导+矩阵快速幂)

    传送门 由于没有考虑n<=1的情况T了很久啊. 这题很有意思啊. 考试的时候根本不会,骗了30分走人. 实际上变一个形就可以了. 推导过程有点繁杂. 直接粘题解上的请谅解. 不得不说这个推导很妙 ...

  3. BZOJ 2326: [HNOI2011]数学作业( 矩阵快速幂 )

    BZOJ先剧透了是矩阵乘法...这道题显然可以f(x) = f(x-1)*10t+x ,其中t表示x有多少位. 这个递推式可以变成这样的矩阵...(不会用公式编辑器...), 我们把位数相同的一起处理 ...

  4. [HNOI2011]数学作业 矩阵快速幂 BZOJ 2326

    题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 NNN 和 MMM ,要求计算Concatenate(1..N) Concatenate (1 .. N) ...

  5. 51nod 1242 斐波那契数列的第N项——数学、矩阵快速幂

    普通算法肯定T了,所以怎么算呢?和矩阵有啥关系呢? 打数学符号太费时,就手写了: 所以求Fib(n)就是求矩阵  |  1  1  |n-1  第一行第一列的元素. |  1  0  | 其实学过线代 ...

  6. Codeforces Round #362(Div1) D Legen...(AC自动机+矩阵快速幂)

    题目大意: 给定一些开心串,每个串有一个开心值,构造一个串,每包含一次开心串就会获得一个开心值,求最大获得多少开心值. 题解: 首先先建立AC自动机.(建立fail指针的时候,对val要进行累加) 然 ...

  7. 刷题总结—— Scout YYF I(poj3744 矩阵快速幂+概率dp)

    题目: Description YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate int ...

  8. hdu 5171 GTY's birthday gift(数学,矩阵快速幂)

    题意: 开始时集合中有n个数. 现在要进行k次操作. 每次操作:从集合中挑最大的两个数a,b进行相加,得到的数添加进集合中. 以此反复k次. 问最后集合中所有数的和是多少. (2≤n≤100000,1 ...

  9. (中等) 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 ...

随机推荐

  1. windows android ndk的某些编译工具报错乱码0x5 或拒绝访问05

    在IDEA或者AndroidStudio的快捷方式上右键属性 > 兼容性 > 以管理员身份运行 解决问题.

  2. Python中的锁

    一.全局解释器锁(GIL) 1.什么是全局解释器锁 在同一个进程中只要有一个线程获取了全局解释器(cpu)的使用权限,那么其他的线程就必须等待该线程的全局解释器(cpu)使用权消失后才能使用全局解释器 ...

  3. 一次 Spark SQL 性能提升10倍的经历(转载)

    1. 遇到了啥问题 是酱紫的,简单来说:并发执行 spark job 的时候,并发的提速很不明显. 嗯,且听我慢慢道来,啰嗦点说,类似于我们内部有一个系统给分析师用,他们写一些 sql,在我们的 sp ...

  4. 【LeetCode每天一题】Simplify Path(简化路径)

    Given an absolute path for a file (Unix-style), simplify it. Or in other words, convert it to the ca ...

  5. Postman代码测试工具如何用?

    1.  1)get请求,参数为map时, postman的传参 2)参数为基本数据类型的参数时 postman传参: 3)当参数在接口中动态获取时 postman传参: 2.  1)post请求,参数 ...

  6. IMU 标定 | 工业界和学术界有什么不同?

    点击"计算机视觉life"关注,置顶更快接收消息! 由于格式问题最好在公众号上观看<IMU 标定-工业界和学术界有什么不同?> 本文主要介绍了IMU基本结构原理和误差的 ...

  7. upCode

    更新源码 Sub main() Dim str As String str = "这是测试的字符串对话框" MsgBox str Sheets(1).Select End Sub

  8. nodejs:导出Excel和解析导入的Excel

    用的是koa2框架,但好好处理一下,用express框架也是可以的.导出的Excel是xlsx的格式,解析导入Excel的有xlsx和csv格式.通常导入Excel是要上传的,然后获取文件的路径,这里 ...

  9. Bioinfo online workshop

    http://icb.med.cornell.edu/index.html%3Fpage_id=2068.html 1. Datacamp https://www.datacamp.com/cours ...

  10. 多线程之CEvent

    最近工作中要维护一个windows模块,用到了mfc中的CEvent类.这算是很久很久以前的老朋友了吧,估计和我超过10年没见过面了,不过工作就是工作,技术上来不得半点含糊,所以还是重新认识一下这位老 ...