CSP-S 2025 游记 & 题解

游记

Day -?

初赛获得了 \(95\text{pts}\),喜提 S > J。

Day -?

不报 J 组了。

Day -1

获得了 \(0(100)+10+0+0=10(110)\) 分。

感觉自己 \(rp\leftarrow rp+\infty\) 了,这就是信心赛吗!!!!111。

Day 0

复习了 KMP 和最小表示法,学了全源最短路和原根。

下午把 Two Avenues 调过了。

感觉要输了。

说了点 P 话。

发现讨论区变成 P 话区了,自愧不如,P 话水平还是太菜了。

Day 1

上午摆摆摆,说了点 P 话。

入场了,提前了 3 分钟开考,zip 解压了半天密码才输对。

看 T1,感觉不会啊。

如果没有限制怎么做,这不是傻逼吗?

加入限制怎么做,这不是傻逼吗?

会了。

看 T2,不知道是神奇建图,还是神奇 \(2^k\)

玩了一下,不会神奇建图,所以是神奇 \(2^k\)

生成树边集归并一下就行了。

看 T3。看成可以替换很多次,想了 \(10\text{min}\)

发现看错了。然后想到了把 LCP 和 LCS 去掉,Hash 一下划分等价类。

等价类里怎么做,思考了大半天,不会了。

然后把划分等价类调出来了,尝试写一个哈希暴力,调不出来,生气了,遂改成 substr 直接比较。大样例飞快何意味?

看 T4,感觉做不出来,写了个阶乘。

废了,退役了。

出考场,发现 T3 在中间插入特殊字符就是我们的【模板】AC 自动机(简单版)。怒了。

想了一下 T2 好像有可能被卡成 \(80\text{pts}\)

@oyoham 差点 AK 了,sto oyoham orz。

垫底了。没有厕所了。

水群,发现没有判 \(|t_1|\neq |t_2|\),玉玉了。交到民间数据上,发现有 \(80 \text{pts}\)。不玉玉了。

无聊,花了不到 \(1\text{h}\) 速通了 J 组。

感觉大家都考得比我好,还是玉玉了。熬到凌晨一点发了一下颠。

策略总归有点问题。考场上心态还是很差啊。

得分是 \(100+[80,100]+[0,80]+8=[188,288]\),随机分数这一块。

抛开【】不谈,难道这个 CSP-S 它就没有问题吗!!!

我想说:

我是彩笔。

题解

T1

如果没有各组人数 \(\leq\dfrac{n}{2}\) 的限制,每个人贪心选最大的那组就行了。

现在加入这个限制,考虑在原来贪心的基础上做调整。显然在原来的贪心策略中,至多有一组不合法。考虑把这一组超出的部分移到其他组里去,然后我们发现这样另外两组一定还满足限制,所以把超出限制的那一组中的所有数,按最大值减次大值排序,贪心选即可。时间复杂度 \(\mathcal{O}(n\log{n})\),可以用 nth_element 做到 \(\mathcal{O}(n)\)

T2

重要的观察是,计算两个边集的并的生成树,只用保留两个边集各自生成树的对应边集。

\(2^k\) 枚举子集,对每个状态维护对应生成树,枚举到 \(S\) 的时候把其 \(\operatorname{lowbit}\) 对应的元素 \(x\)\(n\) 条边和 \(S-\{x\}\) 的生成树的 \(n-1\) 条边放一起归并跑 Kruskal,时间复杂度是 \(\mathcal{O}(m\log{m}+2^kn\alpha(n)+kn\log{n})\)

T3

对于每个字符串二元组 \((s_1,s_2)\),考虑把它们的 LCP 和 LSP 去掉,剩下中间部分变成 \((mid_1,mid_2)\)。对所有 \(s,t\) 都这样做,可以发现,对于一组询问 \((t_1,t_2)\),可能的替换串 \((s_1,s_2)\) 对应的 \(mid\) 二元组一定和 \((t_1,t_2)\) 的相同。使用 Hash 按照 \((mid_1,mid_2)\) 划分等价类。对每个等价类分开做,设 \(t_{i,1},t_{i,2}\) 的 LCP 和 LCS 分别为 \(pret_i,suft_i\)\(s_{i,1},s_{i,2}\) 的分别为 \(pres_i,sufs_i\),那么一个询问相当于求有多少 \(j\) 满足 \(pres_j\)\(pret_i\) 的后缀,且 \(sufs_j\)\(pres_i\) 的前缀。

赛时想到这里就不会了。事实上,我们只需要在 \(pre,suf\) 之间插入特殊字符,那问题就直接变成了求有多少模式串是给定文本串的子串。直接上 AC 自动机就可以做到 \(\sum|t_i|+|\Sigma|\sum|s_i|\)

T4

往 DP 上想,我们的状态里大概要有 \(f_{i,j}\) 表示考虑 \(p_{1\sim i}\),有 \(j\) 个人失败的方案数,但这样似乎还要状压维护失败的人的集合,死完了。

我们考察一个人一定会失败的条件:若 \(s_i=0\),则所有人一定失败;若 \(s_i=1\),则 \(c_i\leq j\) 的人一定失败。这启发我们把人划分成 \(c_i\leq j\)\(c_i>j\) 的集合,然后贡献延后计算,在每次 \(j\rightarrow j+1\) 时,会有一部分人从 \(c_i>j\) 的集合移动到 \(c_i\leq j\) 的集合,我们在这时候乘上这些人的方案数贡献。

\(f_{i,j,k}\) 表示考虑 \(p_{1\sim i}\),有 \(j\) 个人失败,有 \(k\) 个人的 \(c_i>j\) 的方案数。设 \(buc_i=\sum\limits_{j=1}^n[c_j=i]\)\(pre_i=\sum\limits_{j=0}^ibuc_j\),我们分类讨论,刷表转移:

  • \(s_i=0\):此时所有人都会失败,\(j\) 一定会 \(+1\),枚举 \(p_{1\sim i-1}\)\(k\) 个未确定的人中有 \(t\) 个人满足 \(c=j+1\)
    • \(c_i>j+1\):这种 case \(p_i\) 会使得 \(k\)\(1\),于是

      \[f_{i,j,k}\binom{buc_{j+1}}{t}k^{\underline{t}}\rightarrow f_{i+1,j+1,k-t+1} \]

    • \(c_i\leq j+1\):这种 case 要乘上选 \(p_i\) 的方案数,也就是

      \[f_{i,j,k}\binom{buc_{j+1}}{t}k^{\underline{t}}(pre_{j+1}-(i-(k-t)))\rightarrow f_{i+1,j+1,k-t} \]

  • \(s_i=1\)
    • \(c_i>j\)\(f_{i,j,k}\rightarrow f_{i+1,j,k+1}\)
    • \(c_i\leq j\):这种 case \(j\)\(+1\),还要乘上选 \(p_i\) 的方案数,仿照前面的转移,枚举 \(p_{1\sim i-1}\)\(k\) 个未确定的人中有 \(t\) 个人满足 \(c=j+1\)

      \[f_{i,j,k}\binom{buc_{j+1}}{t}k^{\underline{t}}(pre_j-(i-k))\rightarrow f_{i+1,j+1,k-t} \]

注意到 \(t\)\(\mathcal{O}(buc_{j+1})\) 量级的,所以对于固定的 \(i,k\),枚举所有 \((j,t)\) 是整体 \(\mathcal{O}(n)\) 的,于是整个 DP 时间复杂度是 \(\mathcal{O}(n^3)\) 的。

posted @ 2025-11-03 12:41  P2441M  阅读(15)  评论(0)    收藏  举报