CF1089I & P7278
CF1089I#
看到连续段,考虑上析合树。
因为不存在长度为 的连续段,根是析点,它有 个长度为 的儿子。
正难则反,考虑反着做。
- 根是析点
考虑枚举根的儿子数目与排列方式。前者是经典划分数 dp,。后者是一个子问题,可设 为析点的 个子树的排列数,其中并不包含非平凡连续段。答案为 。
- 根是合点
不妨假设根的儿子升序排列,枚举第一个儿子的长度即可。
设 为如此的方案数:, 为一个连续段。有 。此时的方案数即为 。
析合树好抽象。因为不大了解它的结构,甚至不会自己设计 dp 状态了。但是说到底又看着好简单啊,唉。
int main() {
int n = 400, q; scanf("%d %d", &q, &mod);
initC(n + 1);
std::vector<modint> f(n + 1), g(n + 1);
std::vector<std::vector<modint>> s(n + 1, std::vector<modint>(n + 1));
s[0][0] = 1;
f[1] = 1, f[2] = 2;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++)
for (int k = 1; k <= i; k++)
s[i][j] += s[i - k][j - 1] * fac[k];
g[i] = fac[i];
for (int j = 1; j <= i - 1; j++)
g[i] -= g[j] * fac[i - j];
if (i < 4) continue;
f[i] = fac[i];
for (int j = 4; j <= i - 1; j++) f[i] -= s[i][j] * f[j];
f[i] -= 2 * (fac[i] - g[i]);
}
while (q--) {
int x; scanf("%d", &x); printf("%d\n", f[x]);
}
}
P7278#
考虑有什么地方要改过来。
析点时的划分, 拥有上限。根是合点时,最长的连续段是去掉第一个连续段或者去掉最后一个连续段得到的,因此这两个连续段长度不超过 。枚举这两段的长度,中间可以随便排。
int main() {
int n, m; scanf("%d %d", &n, &m);
initC(n);
std::vector<std::vector<modint>> h(n + 1, std::vector<modint>(n + 1));
h[0][0] = 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= i && k <= m; k++)
h[i][j] += h[i - k][j - 1] * fac[k];
std::vector<modint> f(n + 1), g(n + 1);
std::vector<std::vector<modint>> s(n + 1, std::vector<modint>(n + 1));
s[0][0] = 1;
f[1] = 1, f[2] = 2;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++)
for (int k = 1; k <= i; k++)
s[i][j] += s[i - k][j - 1] * fac[k];
g[i] = fac[i];
for (int j = 1; j <= i - 1; j++)
g[i] -= g[j] * fac[i - j];
if (i < 4) continue;
f[i] = fac[i];
for (int j = 4; j <= i - 1; j++) f[i] -= s[i][j] * f[j];
f[i] -= 2 * (fac[i] - g[i]);
}
modint ans = fac[n];
for (int i = n - m; i <= m; i++)
for (int j = n - m; j <= m && j <= n - i; j++)
ans -= 2 * g[i] * g[j] * fac[n - i - j];
for (int i = 4; i <= n; i++)
ans -= h[n][i] * f[i];
printf("%d\n", ans);
}
作者:purplevine
出处:https://www.cnblogs.com/purplevine/p/17999759
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
本文来自博客园,作者:purplevine,转载请注明原文链接:https://www.cnblogs.com/purplevine/p/17999759
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下