【矩阵快速幂优化DP】【校内测试】

【矩阵快速幂优化DP】【校内测试】

实际上是水水题叻,先把朴素DP方程写出来,发现$dp[i]$实际上是$dp[i-k]-dp[i-1]$的和,而看数据范围,我们实际上是要快速地求得这段的和,突然就意识到是矩阵快速幂叻。

构建矩阵什么的还是很简单滴,主要就是练一练手。

(还有就是水一水blog!换个字体,换个心情!

(快速乘是在模数很大时要用,避免超long long

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define mod 7777777 LL k, n, dp[]; struct Matrix {
LL w[][];
} base; struct Node {
LL w[][];
} pool; Matrix Cheng(Matrix a, Matrix b) {
Matrix ans;
for(int i = ; i <= k; i ++)
for(int j = ; j <= k; j ++)
ans.w[i][j] = ;
for(int i = ; i <= k; i ++)
for(int j = ; j <= k; j ++)
for(int p = ; p <= k; p ++)
ans.w[i][j] = (ans.w[i][j] + a.w[i][p] * b.w[p][j] % mod) % mod;
return ans;
} Matrix mpow(Matrix a, LL b) {
Matrix ans;
for(int i = ; i <= k; i ++)
for(int j = ; j <= k; j ++)
if(i == j) ans.w[i][j] = ;
else ans.w[i][j] = ;
for(; b; b >>= , a = Cheng(a, a))
if(b & ) ans = Cheng(ans, a);
return ans;
} int main() {
freopen("fyfy.in", "r", stdin);
freopen("fyfy.out", "w", stdout);
scanf("%lld%lld", &k, &n);
for(int i = ; i <= k; i ++)
for(int j = ; j <= k; j ++) base.w[i][j] = ;
for(int i = ; i <= k; i ++) base.w[][i] = ;
for(int i = ; i <= k; i ++) base.w[i][i-] = ;
dp[] = ;
for(int i = ; i <= k; i ++)
for(int j = ; j <= i; j ++)
dp[i] = (dp[i] + dp[i-j]) % mod;
for(int i = ; i <= k; i ++) pool.w[i][] = dp[k-i+];
base = mpow(base, n-k);
LL ans = ;
for(int i = ; i <= k; i ++) ans = (ans + base.w[][i] * pool.w[i][] % mod) % mod;
printf("%lld", ans);
return ;
}
上一篇:CENTOS 配置好SVN服务环境后,其他服务器无法访问 Error: Can't connect to host '192.168.1.103': 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。


下一篇:mysql sql语句