CSP-S 2024 第六次
A
排序之后只会选相邻的,直接 DP。
B
从前往后考虑每个数
若不删
- 若
,则 已经确定。 - 若
,则 可取所有没出现过的数,以及 后最小的数(先删掉它再把 赋成它)
若删掉
- 若
,则 会变成 。 - 若
,则 可取所有没出现过的数(删除操作给 了,所以没法取 后最小的数),然后 会变成 。
若不删
确定删掉的数之后,把没出现过的数从小到大填到空位里即可。
C
先把边权为 0 的边缩起来。
钦定
用 set 维护虚树点集即可。
D
先设
可以用分组背包的形式转移,枚举
对于
再设
转移同理,枚举
对于
则根恰有两个子树,直径个数为两个子树中深度为
枚举两个子树的大小,深度为
顶针要代码,那就放一下代码:
#include <cstdio>
#include <cstring>
#define M 998244353
#define int long long
bool F;
int n, k, p, o, v[50], g[50][50][50], G[50][50];
int C(int n, int k)
{
int q = 1;
for (int i = n + k - 1; i >= n; --i)
q = q * i % M;
for (int i = 1; i <= k; ++i)
q = q * v[i] % M;
return q;
}
signed main()
{
freopen("dia.in", "r", stdin);
freopen("dia.out", "w", stdout);
v[1] = 1;
for (int i = 2; i <= 40; ++i)
v[i] = (M - M / i) * v[M % i] % M;
scanf("%lld%lld%lld", &n, &k, &p);
if (k & 1)
F = 1;
k = k + 1 >> 1;
g[1][1][1] = 1;
for (int vn = 1; vn <= n; ++vn)
for (int vl = 1; vl <= k; ++vl)
for (int vp = 1; vp <= vn; ++vp)
for (int un = n - vn; un >= 1; --un)
for (int ul = 1; ul <= k; ++ul)
for (int up = 1; up <= un; ++up)
for (int t = 1; un + vn * t <= n; ++t)
{
int _ = C(g[vn][vl][vp], t);
if (vl + 1 > ul)
g[un + vn * t][vl + 1][vp * t] = (g[un + vn * t][vl + 1][vp * t] + g[un][ul][up] * _) % M;
else if (vl + 1 == ul)
g[un + vn * t][ul][up + vp * t] = (g[un + vn * t][ul][up + vp * t] + g[un][ul][up] * _) % M;
else
g[un + vn * t][ul][up] = (g[un + vn * t][ul][up] + g[un][ul][up] * _) % M;
}
for (int vn = 1; vn <= n; ++vn)
for (int vp = 1; vp <= vn; ++vp)
{
G[vn][vp] = (G[vn][vp] + g[vn][k][vp]) % M;
for (int vl = 1; vl < k; ++vl)
G[vn][0] = (G[vn][0] + g[vn][vl][vp]) % M;
}
if (!F)
{
int f[50][50][50];
memset(f, 0, sizeof f);
f[1][0][0] = 1;
for (int vn = 1; vn <= n; ++vn)
for (int vp = 0; vp <= vn; ++vp)
for (int un = n - vn; un >= 1; --un)
for (int ud = 0; ud <= p; ++ud)
for (int up = 0; up <= un && ud + up * vp <= p; ++up)
{
int _d = ud + vp * up, _p = up + vp;
for (int t = 1; un + vn * t <= n && _p <= n && _d <= p; ++t, _d += vp * _p, _p += vp)
{
int _ = C(G[vn][vp], t);
f[un + vn * t][_p][_d] = (f[un + vn * t][_p][_d] + f[un][up][ud] * _) % M;
}
}
int z = 0;
for (int i = 0; i <= n; ++i)
z = (z + f[n][i][p]) % M;
printf("%lld", z);
}
else
{
int z = 0;
for (int vn = 1; vn <= n; ++vn)
for (int vp = 0; vp <= vn; ++vp)
for (int un = 1; un <= n; ++un)
for (int up = 0; up <= un; ++up)
if (un + vn == n && up * vp == p)
{
int _z = z;
if (un == vn && up == vp)
z = (z + C(G[un][up], 2) * 2) % M;
else
z = (z + G[un][up] * G[vn][vp]) % M;
}
printf("%lld", z * (M + 1 >> 1) % M);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具