算法
转化题意, 对于一个菊花图, 每次操作可以去到中心点, 再任意找一个外点跑,
首先考虑 \(\rm{dp}\) 的做法
对于每一天的后半部分, 我们考虑前半天走了长路和前一天走了短路两种情况, 显然的, 如果前半天走了长路, 那么后半天一定要走短路, 如果前半天走了短路, 后半天走长路和短路都一样
令 \(f_{i, 0 / 1}\) 表示第 \(i\) 天的前半天走了 短路 / 长路 的情况数量
那么显然的, 转移的系数为组合数
那么这个显然可以预处理用矩阵做
实现
不想重复写一个东西
ctj
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
constexpr int mod = 1000000007;
matrix base, res;
int m, n, s[100005], l[100005];
modint ans, f0, f1;
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> m >> n;
for(int i = 1; i <= m; ++i) cin >> s[i];
for(int i = 1; i <= m; ++i) cin >> l[i];
for(int i = 1; i <= m; ++i) {
base.val[0][0] += (s[i] + l[i]) * s[i], base.val[0][1] += (s[i] + l[i]) * l[i];
base.val[1][0] += s[i] * s[i], base.val[1][1] += s[i] * l[i];
}
res = ksm(base, n - 1);//这里是快速幂优化
f0 = s[1] * res.val[0][0] + l[1] * res.val[1][0];
f1 = s[1] * res.val[0][1] + l[1] * res.val[1][1];
for(int i = 1; i <= m; ++i) {
ans += f0 * (s[i] + l[i]) + f1 * s[i];
}
cout << ans;
return 0;
}
总结
善于推导柿子, 系数确定考虑矩阵加速
标签:int,Trails,短路,Hard,前半天,long,cin,长路 From: https://www.cnblogs.com/YzaCsp/p/18594333