CSP-S 模拟赛 Day 16
CSP-S 模拟赛 Day 16
T1
小技巧:计算子树内单一信息(比如大小为 \(x\) 的子树个数)的时候可以开一个全局的桶,在进入 \(u\) 的打上标记,回溯到 \(u\) 的时候一减,就能得到信息。
T2 弱化版
考虑描述一颗广义的线段树,可以选择用断点描述,对于一个区间,我们通过断点分成两个子区间 \([l,mid]\) 和 \([mid, r]\),所以第 \(d\) 层就变成了一个长度为 \(2^{d-1}\) 的序列,其中每一项都是上面所有区间的断点。
再来看询问,依旧可以把每个区间询问看成断点的形式,也就是左边是 \(l-1\),右边是 \(r\),继续推,考虑当前区间的答案是什么,不难想到其实就是 \(l-1\) 这一侧的区间最大深度 和 \(r\) 这一侧的区间到达的最大深度 的最大值。
不难看出最终 \([l, r]\) 区间的子区间到达最大深度的时候,一定是 \(l-1\) 为断点或者 \(r\) 为断点,所以实际上我们只需要看所有区间到达的最大深度 \(d\),当深度为 \(d-1\) 的时候所有断点一定都是对应区间的。考虑求 \(d\),贪心的来说,如果要让 \(d\) 尽可能的小,肯定要先把深度小的全部填起来先,再来填深度为 \(d\) 的断点,所以 \(d\) 就是满足 \(2 ^ d - 1\) 大于等于总断点数的最小值。
这里先给断点去个重然后直接记录每个断点的数量。
所以不难想到贪心,每个断点都是一个区间的两个端点。总共有 \(2 ^ d - 1\) 个断点,其中第奇数个断点一定是在最后一层的,而只有最后一层算贡献,所以问题变成了往这些格子里面(\(2^{d - 1} \le cnt \le 2 ^d - 1\))填 \(tot\) 个数,使得奇数位的总贡献最少。显然如果第 \(d - 1\) 层答案是 \(res\),那么每一个区间都会向下遍历它的两个儿子,所以最终答案应该是 \(res \times 2\)。
但是注意到偶数位必须全部填满,所以问题又转化成了在 \(tot\) 个数中取 \(cnt - 2^{d-1} - 1\) 个数字做奇数方格,并且他
这个问题就不难用 dp 解决,记 \(f_{i,j}\) 表示考虑到第 \(i\) 个字符,填了前 \(j\) 个数,总共的访问次数,\(f_{i,j} = \min(f_{i,j},f_{i-1,j-1} + a_i[i\equiv 0 \pmod 2])\)。答案就是 \(f_{n, tot}\)。