Loading

Trails (Hard)

算法

转化题意, 对于一个菊花图, 每次操作可以去到中心点, 再任意找一个外点跑,

首先考虑 \(\rm{dp}\) 的做法

对于每一天的后半部分, 我们考虑前半天走了长路和前一天走了短路两种情况, 显然的, 如果前半天走了长路, 那么后半天一定要走短路, 如果前半天走了短路, 后半天走长路和短路都一样

\(f_{i, 0 / 1}\) 表示第 \(i\) 天的前半天走了 短路 / 长路 的情况数量

那么显然的, 转移的系数为组合数

pA7bQoV.png

那么这个显然可以预处理用矩阵做

实现

不想重复写一个东西

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;
}

总结

善于推导柿子, 系数确定考虑矩阵加速

posted @ 2024-12-09 10:19  Yorg  阅读(15)  评论(0)    收藏  举报