一些闲话
期末考,依旧是 AK。
题解
T1
有 \(n\) 个位置。起初每个位置都被封锁。你可以进行以下两种类型的操作:
- 选择一个位置 \(i\),其中 \(1\leq i\leq n\) ,然后解除该位置的封锁;
- 选择一对位置 \(l\) 和 \(r\),其中 \(1\leq l\leq r\leq n\),满足位置 \(l\) 和 \(r\) 都已解除封锁,且从位置 \(l\) 到位置 \(r\) 的已解除封锁的位置数至少为 \(\lceil\frac{r - l + 1}{2}\rceil\),然后将 \(l\) 到 \(r\) 之间的所有位置都解除封锁。
要求最终所有位置都被解锁。最小化操作 \(1\) 的次数。
多测。对于所有测试点,\(1\leq t\leq 10^4\),\(1\leq n\leq 10^5\)。
贪心简单题。考虑一个极长的已被解锁的区间 \([1,r]\),那么显然可以解锁 \(2(r+1)\) 处的位置,然后选取 \((1,2(r+1))\) 进行操作 \(2\)。暴力模拟即可。时间复杂度 \(O(t\log{n})\)。
T2
给定一个数字串 \(s\),你可以进行若干次这样的操作:选取其中一个数字(该数字不为 \(0\) 且不在最左边),将其减小 \(1\),然后与前面的数字交换。试最大化最终的数字串的字典序。
对于所有测试点,\(1\leq|s|\leq 2\times 10^5\)。
还是贪心简单题。要最大化字典序,就肯定要从高到低确定并最大化每一位,直接贪心地选取交换到前面最大的那一位即可。注意到对于每一位,决策集合最多包含从当前位开始的 \(9\) 位,暴力找最大值即可。时间复杂度 \(O(\Sigma n)\)。
扩展:扩大字符集大小。
那么考虑维护原串中每个位置交换到前面得到的数字 \(v_i\)。那么每一次查询全局 \(\max\) 即可。而选定一个最大的位置 \(i\) 后,显然它后面所有位置的交换次数都会减 \(1\),等价于将 \(v[i+1,n]\) 区间加 \(1\),然后再令 \(v_i\leftarrow -\infty\) 即可。于是直接上线段树,就可以做到与字符集大小无关的 \(O(n\log{n})\) 的时间复杂度。
T3
定义一个长度为 \(n\) 的排列 \(p\) 的价值其中所有区间的最小值之和,即
\[\sum_{l=1}^n\sum_{r=l}^n\min_{k=l}^r\{p_k\} \]多次询问 \(n,k\),求出在所有令价值最大化的长度为 \(n\) 的排列中,字典序第 \(k\) 小的排列。
对于所有测试点,\(1\leq q\leq 10^4\),\(1\leq n,\sum{n}\leq 2\times 10^5\),\(1\leq k\leq 10^{12}\)。
先思考令价值最大化的排列具有怎样的性质。对这个式子显然考虑拆贡献,即计算每个 \(p_i\) 延伸出去的极长的以它为最小值的区间。自然地从小到大考虑每个数,对于 \(1\),这个区间长度必然为 \(n\);对于 \(2\),这个区间长度至多达到 \(n-1\),且此时显然要求 \(1\) 在排列的两端……以此类推。于是这个性质就很显然了:从小到大考虑每个数,将它从最左端从左到右地加到排列中,或将它从最右端从右到左地加到排列中。这样构造出来的排列必然能最大化价值。
然后考虑怎么求字典序第 \(k\) 小的排列。这个肯定是和方案数挂钩的。依据刚刚的构造过程,显然有长度为 \(n\) 的令价值最大化的排列共有 \(2^{n-1}\) 种。于是依然从小到大考虑每个数字,根据 \(k\) 的大小判断是往左边还是右边加即可。时间复杂度 \(O(\sum{n})\)。
T4
给出一棵 \(n\) 个点的树。你可以选择其中一条链并将链上的所有节点及其连出去的边全部从树中删去。最大化剩余的节点形成的极大连通块的数量。
对于所有测试点,\(2\leq n\leq 2\times 10^5\)。
无聊题。显然剩余的节点形成的极大连通块的数量,等于与选出来的链相连的边的数量。然后直接树形 DP。令 \(f_{u,0/1}\) 表示从以 \(u\) 为根的子树中选出来的不穿过/穿过 \(u\) 的最优的链的相连边数,进行简单地分类讨论即可。时间复杂度 \(O(n)\)。