2024.03.13 题解

CF566A. Matching Names

注意到要求公共前缀,所以先对所有字符串建出 Trie 树,则公共前缀长度等价于 Trie 树上两节点最近公共祖先的深度。

\(dfn_u\) 表示 u 点的 dfs 序,\(dep_u\) 表示 u 的深度,\(lca_{u,v}\) 表示 \(u\)\(v\) 的最近公共祖先。

则对于 \(dfn_a < dfn_b < dfn_c < dfn_d\),有 \(dep_{lca_{a,b}} + dep_{lca_{c,d}} \ge dep_{lca_{a,d}} + dep_{lca_{b,c}}\ge dep_{lca_{a,c}} +dep_{lca_{b,d}}\)

推广后可知如下贪心是正确的:对于一个节点 \(u\),从其所有后继节点处继承所有未匹配的字符串,将能匹配的匹配,不能匹配的传入父节点,则对于每个节点开两个 queue 存其剩余的笔名和真名,如果均非空则匹配并计入答案。

CF498B. Name That Tune

\(dp_{i,j}\) 表示在第 \(i\) 秒时识别第 \(j\) 首歌的概率。

则答案为:\(\sum\limits_{i = 1}^{t}\sum\limits_{j = 1}^{n}dp_{i,j}\)

考虑转移:枚举识别当前歌用了多久,则有:

\[dp_{i,j} = \sum\limits_{k = 1}^{t_i - 1} dp_{i - 1,j - k}p_i(1 - p_i)^{k - 1} + dp_{i - 1,j - t_i} \]

变形,得:

\[dp_{i,j} = p_i(1 - p_i)^{j - 1}\sum\limits_{k = 1}^{t_i - 1} dp_{i - 1,j - k}(1 - p_i)^{(j - k)} + dp_{i - 1,j - t_i} \]

求和部分可以前缀和优化,但这样精度会爆,我们还是把 \((1 - p_i)^{j - 1}\) 挪回去,这样就可以像求哈希一样动态更新前缀和,再把 \(dp_{i - 1,j - t_i}\) 的贡献从里面减去即可。

核心代码:

double S = pow(1 - p,t - 1);
sum = dp[i - 1][0];
for(int j = 1;j <= T;j++)
{
	if(j >= t)sum -= dp[i - 1][j - t] * S;
	if(j < t)dp[i][j] = p * sum;
	else dp[i][j] = S * dp[i - 1][j - t] + p * sum;
	sum *= 1 - p;
	sum += dp[i - 1][j];
	ans += dp[i][j];
}

CF626F. Group Projects

考虑按能力值从小到大放学生,设 \(dp_{i,j,k}\) 表示现在放了 \(i\) 个学生,还有 \(j\) 组的最大值不确定,总不和谐度为 \(k\)

讨论当前学生作为某一组最大值,既不作为最大值也不作为最小值,作为新一组最小值的情况转移即可。

但这样可能会先将 \(k\) 减去很多个数(将前一部分全作为新一组最小值)再加回来,第三维状态数会非常大,时空都不能接受。

考虑拆分贡献,因为 \(a\) 数组有序,所以:\(a_i - a_j = (a_i - a_{i - 1}) + (a_{i - 1} - a_{i - 2}) + \dots + (a_{j + 1} - a_j)\)

而对于当前枚举的学生 \(i\),所有有最小值而没有最大值的组都会产生 \(a_i - a_{i - 1}\) 的贡献,这个贡献不像之前的有加有减,而是一直加,所以第三位状态数是 \(O(k)\) 的,可以接受。

CF93C. Azembler

发现最多进行 \(O(\log n)\) 次操作,总数量非常少,不满 \(26\) 个,所以我们每一次操作都可以用之前没用过的一个寄存器,同时这也启发我们搜索,因为要记录操作,所以使用迭代加深搜索更方便。

CF704B. Ant Man

发现 \(f(i,j)\)\(i\)\(j\) 的贡献互相独立,考虑分开计算,又发现 \(i\)\(j\)\(f(i,j)\) 中的贡献和他们的相对大小有关,所以考虑连续段 \(dp\)

\(dp_{i,j}\) 表示放入了 \(i\) 后还有 \(j\) 个空段(含最左边和最右边的段),因为给定了最左和最右填什么数,所以这道题不需要考虑这两种特殊情况,转移时枚举当前数左右相邻情况即可,注意特判 \(s\)\(e\) 与转移的合法性。

CF1278F. Cards

发现有 \(\frac{1}{m}\) 的请况合法,记 \(p = \frac{1}{m}\),则期望为:

\[\sum\limits_{i = 1}^{n}\dbinom{n}{i}p^i(1-p)^{n - i}i^k \]

\(i^k\) 不太好算,可以利用其与下降幂的关系分解,得:

\[\sum\limits_{i = 1}^{n}\dbinom{n}{i}p^i(1-p)^{n - i}\sum\limits_{j = 1}^{k}\begin{Bmatrix}k\\j\end{Bmatrix}i^{\underline{j}} \]

交换求和位置,得:

\[\sum\limits_{j = 1}^{k}\begin{Bmatrix}k\\j\end{Bmatrix}\sum\limits_{i = 1}^{n}\dbinom{n}{i}p^i(1-p)^{n - i}i^{\underline{j}} \]

把下降幂和组合数拆了,得:

\[\sum\limits_{j = 1}^{k}\begin{Bmatrix}k\\j\end{Bmatrix}\sum\limits_{i = 1}^{n}\frac{n!}{(n - i)!(i - j)!}p^i(1-p)^{n - i} \]

考虑给 \(p^i(1-p)^{n - i}\) 凑出一个二项式定理,由于我们拆不掉 \((n - i)!(i - j)!\),所以我们只能去动 \(n!\) 得:

\[\sum\limits_{j = 1}^{k}\begin{Bmatrix}k\\j\end{Bmatrix}p^jn^{\underline{j}}\sum\limits_{i = 1}^{n}\dbinom{n - i}{i - j}p^{i - j}(1-p)^{n - i} \]

后面的求和是等于 \(1\),式子化简为:

\[\sum\limits_{j = 1}^{k}\begin{Bmatrix}k\\j\end{Bmatrix}p^jn^{\underline{j}} \]

\(O(k^2)\) 递推斯特林数即可。

CF1110F. Nearest Leaf

考虑离线,记录 \(dis_i\) 表示 \(i\) 到根的距离,如果 \(i\) 不是叶子,则将 \(dis_i\) 赋为 \(+\infty\),对根的询问即为区间查询,考虑根从 \(u\) 移动到相邻节点 \(v\)\(u\)\(v\) 的距离为 \(w\)\(dis\) 的变化,可知对于 \(v\) 子树内的点,\(dis\) 将减少 \(w\),对于其他的点,\(dis\) 将增加 \(w\),由于给定的编号即为 dfs 序,所以一个子树内的编号是连续的,变化为区间修改,整体可用线段树维护。

CF293B. Distinct Paths

发现 \(n + m - 1 > k\) 时显然无解,所以 \(nm\) 的最大值为 \(30\),考虑爆搜,发现对于一个空白的点,我们给他赋上所有没出现过的颜色是等价的,可以合并计算。同时如果从 \((1,1)\)\((i,j)\) 的颜色集合大小超过了 \(k - i - j\),则无解。

加入上述两个剪枝后即可通过。

posted @ 2024-03-13 21:02  BlNYU  阅读(18)  评论(0编辑  收藏  举报