考完了还是来写一下题解。
Day1
T1 - 格雷码
确定最高位并按题意递归到子问题即可。注意开 unsigned long long
。
T2 - 括号树
显然的是我们只需要求从当前节点往根走的最短的合法括号序列即可。当前字符如果是 )
,则路径一定不合法,反之,设 (f[x]) 表示根到当前的路径的左括号个数减右括号个数,当前节点到最后一个出现的 (f[x]) 一定是最短的合法括号序列。开桶记录,并且在dfs结束时进行撤销即可。
T3 - 树上的数
因为求的是字典序,我们考虑依次确定最小能填多少。考虑最终 (x) 从 (a) 走到了 (b),对于整个结果的影响其实是对于路径上的每个节点,与之相邻的边的先后操作顺序加入了一个限制。限制形如:一条边必须紧接在另一条边之后操作,或一条边应该在最先/最后操作。
用并查集维护当前的位置,依次 dfs,暴力判断一个节点是否能行即可。当然并查集可以换成直接维护每段确定的顺序的最先/最后一条边,不过并不会得到更好的复杂度(都是 (O(n^2)) )。
Day2
T1 - Emiya家今天的饭
考虑最多有一个位置不满足 (lfloor n/2 floor) 的条件,并且转化一下其实是这个位置选的要比其它的和还要多。
枚举是哪一个位置,记录一下选的个数的差做dp。
T2 - 划分
证明不会。
感性理解/打表/假装他是对的,发现每个位置贪心的选最接近的一个是正确的。
(nlog n) 非常简单,暴力对每个位置二分贡献到的区间即可。
线性做法可以用一个单调队列/单调栈/单调xxx维护。
最后要加高精度。
T3 - 括号树
目前不会线性做法。
对每个点统计它是重心的方案数。
枚举每个出度,每条边有一个以当前点为根的子树大小的限制(一段区间)。
冷静分析,发现询问可以转化为(以1号点为根的dfs序,子树大小)的二维数点,或者当前点到一号点的根的区间查询。
询问离线树状数组或直接主席树即可做到 (O(nlog n))。