首页 > 其他分享 >CSP-S2019

CSP-S2019

时间:2024-10-17 10:21:10浏览次数:13  
标签:pre le 重心 sum 子树 S2019 gets CSP

括号树

题意:给定一棵树,以 \(1\) 为根,每个点有字符 ()

定义 \(s_i\) 为 \(i\) 到根的路径的子串中合法括号序列的个数,求 \(\bigoplus_{i = 1}^n i \times s_i\),\(1 \le n \le 5 \times 10^5\)。

记 \(p_i\) 为 \(i\) 的父亲,\(a_i\) 为 \(i\) 到根的路径以 \(i\) 结尾的合法括号序列个数。

显然有 \(s_i = s_{p_i} + a_i\),只要求 \(a_i\) 即可。

dfs 过程中模拟栈匹配,假设 \(i\) 是 ) 且能和某个未被匹配的 ( \(j\) 匹配,\(a_i = a_j + 1\)。

时间复杂度 \(O(n)\)。submission

划分

题意:长度为 \(n\) 的数组 \(\{a\}\),求一个划分 \(S = \{p_1, p_2, \cdots, p_k\}\) 满足:

\[\sum_{i = 1}^{p_1}a_i \le \sum_{i = p_1 + 1}^{p_2}a_i \le \cdots \le \sum_{i = p_k + 1}^{n}a_i \]

最小化

\[(\sum_{i = 1}^{p_1}a_i)^2 \le (\sum_{i = p_1 + 1}^{p_2}a_i)^2 \le \cdots \le (\sum_{i = p_k + 1}^{n}a_i)^2 \]

数据范围:\(1 \le n \le 4 \times 10^7\)。

设 \(f(i, j)\) 表示长度为 \(i\) 的前缀,最后一个分割点在 \(j\) 的最小值:

\[f(i, j) =(s_i - s_j)^2 + \min_{(s_i - s_j)^2 \ge (s_j - s_k)^2}f(j, k) \]

存在结论:\(f(i, j) \le f(i, j - 1)\)。

  • 只有一个分割点,两部分分别为 \(x, y\),在 \(y - x > 1\) 的前提下,\(x \gets x - 1,\ y \gets y - 1\) 显然更优。

  • 否则设分割点数为 \(k\),假设对于 \(1 \sim k - 1\) 都已经满足这个性质。

    将最后一个点左移:

    假设存在 \(j\),使得 \(1 \sim j\) 保持不动,\((j + 1, k]\) 集体左移,在维持不降性质的同时使答案变小。

    可以看作 \([p_j + 1, i]\) 上的一个子问题,而其规模小于 \(k\),已经被证明不优了;

    否则所有分割点集体左移,设第 \(i\) 段长度为 \(l_i\),存在一种最优方案使前 \(k\) 段每段长度不增。

    即:\(l_i \gets l_i - x_i,\ l_{k + 1} \gets l_{k + 1} + \sum x_i\)。

    结论成立的一个充分条件为:\(l_i \gets l_i - 1,\ l_{k + 1} \gets l_{k + 1} + 1\) 不优,这是显然的。

因此每个 \(f(i)\) 的转一段是唯一的,记作 \(pre_i\)。

需要满足 \(s_i - s_{pre_i} \ge s_{pre_i} - s_{pre_{pre_i}}\),移项即 $s_i \ge 2s_{pre_i} - s_{pre_{pre_i}} $。

单调栈找到最大的 \(j\) 满足 \(s_i \ge 2s_j - s_{pre_j}\),那么 \(pre_i = j\),时间复杂度 \(O(n)\)。

不是很懂为什么要卡空间,把 \(pre\) 处理出来后从后往前扫一遍即可,只要开一个 i128

submission

树的重心

题意:\(x\) 为树的中心当且仅当其最大子树大小不超过 \(\lfloor\frac{n}{2}\rfloor\),一棵树只可能有一个或两个重心。

删去边 \(e\) 使整棵树分裂为两部分,求:

\[\sum_{e \in E}\bigg(\sum_{x\text{ 是 }T_1\text{ 的重心}}x + \sum_{y\text{ 是 }T_2\text{ 的重心}}y\bigg) \]

数据范围:\(n \le 3\times 10^5\)。

选定原树的一个重心作为根 \(rt\)。

先考虑 \(x \ne rt\) 的情况。

如果断点一条边后 \(x\) 是重心,那么这条边不可能出现在 \(x\) 子树内。

记 \(s_x\) 为 \(x\) 子树大小,则 \(s_x \le \lfloor\frac{n}{2}\rfloor\),如果断在子树内,则包含一棵大小为 \(n - s_x\) 的子树,与 \(x\) 是重心矛盾。

设 \(g_x\) 为 \(x\) 最大子树大小,\(S\) 为另一棵数的大小,需要满足:

\[\begin{cases} 2g_x\le n - S\\ \\ 2(n - S - s_x) \le n - S \end{cases} \]

整理一下:

\[n - 2s_x \le S \le n - 2 g_x \]

对于一个 \(x\),要找满足以下条件的边的个数:

  • \(n - 2s_x \le S \le n - 2 g_x\)。
  • 不在 \(x\) 子树内。

只考虑第一个限制:对于 \(fa_u\) 到 \(rt\) 的链,\(S = n - s_y\),其他地方 \(S = s_y\),容易用树状数组维护。

利用出入子树时的增量把第二部分容斥掉(可以线段树合并)。

考虑 \(rt\) 作为根的次数,只关心最大子树 \(x\) 和次大子树 \(y\),分类讨论断边位置即可。

submission

树上的数

讲一下 CSP-S 史上最难题《树上的数》(只需入门组知识就能做的黑题)

标签:pre,le,重心,sum,子树,S2019,gets,CSP
From: https://www.cnblogs.com/Luxinze/p/18471515

相关文章

  • 「模拟赛」CSP-S 模拟 11(T2 超详细)
    比赛链接A.玩水(water)签到。发现如果要找两条路径的话,能找到的充要条件是存在一个点的上方和左方的字母相同。(即使两条走过的点截然不同的路径也符合,这时终点会成为这个点)。即存在一个位置\((i,j)\)使得\(s_{i-1,j}=s_{i,j-1}\),我们称位置\((i,j)\)是好位置。扩展到三......