题目记录(Before 省选 ver.)
T1. P6891
首先考虑有没有 \(\mathrm O(n^2)\) 的做法。此时考虑定义 \(dp_{i,j,A/B}\) 表示目前选了 \(i\) 个数,其中有 \(j\) 个是 \(A\) 数组里的,最后一个数是 \(A\) 还是 \(B\) 中的。
然后此时考虑定义 \(dp_{i,A/B,0/1}\) 表示当前选择了 \(i\) 个数,其中最后一个选的是 \(A\) 还是 \(B\) 数组里的,\(A\) 最大/最小有多少个。
那么此时的转移就很简单了,可以做到 \(\mathrm O(n)\) 转移。构造答案可以直接倒着构造。
T2. AT_arc202_c
首先有 \(R_{\gcd(x,y)} = \gcd(R_x,R_y)\)。
注意到 \(\text{gcd}\) 和 \(\text{lcm}\) 的本质其实是对于所有因数的幂次取 \(\min\) 或者取 \(\max\)。
发现题目要求的形式是求一个集合的 \(\text{lcm}\),然后根据上面的观察,考虑对于这个东西做一个 \(\min-\max\) 容斥得:
这个 \(\text{gcd}\) 不好处理,所以考虑把它转化为有关于因数的,则考虑定义 \(R_n = \prod_{i \mid n} F_i\),则我们有:
则考虑把 \(i\) 放到外面枚举,可得:
然后只需要用反演求出 \(F_d\) 即可。
T3. P14455
简单构造题,场掉了。
假如我们设 \(1\) 为这棵树的根节点,那么 \(w_{1,i} \oplus w_{1,j} \oplus w_{i,j}\) 就可以确定 \(i,j\) 的 \(\text{lca}\) 的编号。
然后考虑对于每一个点都维护其子树集合,然后按照这个集合的大小从小到大去考虑节点即可。具体的,如果遇到非叶子节点 \(u\),考虑去枚举他的子树中的所有点然后看有那些节点没有找到父亲,这些点的父亲就一定是 \(u\)。
T4. P14830
很牛牛的题啊!
发现直接求 border 不好搞啊,所以考虑把字符串反过来然后倒着差入变为 \(a_1 a_n a_2 a_{n-1} \cdots\),然后你发现求 border 变成了求回文串个数。除了回文串还有一下两个要求:
-
长度是偶数。
-
从奇数位开始。
然后我们发现支持每一次求一遍马拉车,所以复杂度就是 \(\mathrm O(nq)\)。
T5. P7603
折半报警器。
注意到 \(x \le n \le 10^5\),所以每一次闹鬼至多会修改 \(6\) 个位置的值。
根据抽屉原理可得若 \(\sum_{1 \le i \le k} a_i \ge y\),则一定存在一个 \(a_i \ge \lceil \frac{y}{k} \rceil\)。那么此时我们考虑给这个集合里面的所有数塞一个大小为 \(\lceil \frac{y}{k} \rceil\) 的报警器。如果一个监控器中的某一个报警器报警了,那么我们就考虑直接暴力去查看这个监控器会不会报警,但是我们肯定不能接受这个复杂度。
我们发现我们只要有一个报警器报警了,那么我们在之后的每一次修改都需要暴力检查一遍,这样是不优的。所以考虑当一个报警器报警后,看当前是否会让这个监控器报警,否则计当前闹鬼次数的和为 \(s\),然后重新塞进来一个 \(\lceil \frac{y - s}{k} \rceil\) 的报警器。
时间复杂度为 \(\mathrm O(k^2 \log V \log q)\)。
T6. CF2066E
考虑两个水量相等的水桶,如果他们测出来重量不一样,那么较重的那一个是有毒的,否则这两个水桶内的水就是可以随便倒的。
此时考虑记录一个值 \(L\) 表示目前我们可以随便倒的水的水量。那么我们发现所有的操作都可以归约为一下两种:
-
选择一个 \(a_i \le L\):就是用 \(L\) 去装一个水量为 \(a_i\) 的桶去和 \(a_i\) 比,如果是一样重的那么 \(L \gets L + a_i\)。
-
选择一个 \(a_i + L \ge a_j\):往 \(a_i\) 内倒 \(a_j - a_i\) 的水然后再和 \(a_j\) 比较,如果一样重那么 \(L \gets L + a_i + a_j\)。
此时发现我们最开始的第一个操作可以视为 \(L = 0\),然后选择两个相同重量的桶去做 \(2\) 操作。然后我们一直进行上面两个操作,直到我们可以确定 \(n - 1\) 个桶内没有毒药为止。
考虑用值域分块来优化这个过程。那么就是将 \([2^i,2^{i+1})\) 内的数分成一个块。此时我们发现两个操作后都一定会比这个块内的最大值要大,所以如果我们确定了某一块内任意一个桶没有毒药,那么就可以确定一整块所有的桶是否有毒药。
然后我们发现对于一个块 \(S\) 能否有一个被确定的条件为 \(L \ge \min \limits_{x \in S} a_x\) 或者 \(L \ge \min \limits_{x \in S,y \in [1,n]} (|a_x - a_y|)\)。那么我们只需要对于每一个块都再维护一个相邻两个数的差即可。
T7. P9545
先把最大流转成最小割,那么考虑令 \(f(S,T)\) 表示起点集合为 \(S\),终点集合为 \(T\) 的最小割,那么很明显 \(f(S,T) = \sum_{u \in S,v \in T} e_{u,v}\),其中 \(e_{u,v}\) 表示 \(u \to v\) 的有向边是否存在。
此时发现 \(f(S,T) + f(T,S) = |S| \times |T|\)。而同时又发现,对于一条边如果他对 \(S\) 的贡献为 \(1\),那么它对于 \(T\) 的贡献就是 \(-1\),所以 \(f(S,T) - f(T,S) = \sum_{u \in S} out_u - in_u\)。又因为 \(|S|\) 相同,所以我们考虑贪心的去取 \(S\) 即可。
T8. P7564
很牛的题目。
考虑把所有人看成一条从(出发时间,出发位置)到(终止时间,终止位置)的线段,那么每个用户就是一条从 \((t_i,a_i)\) 到 \((t_i + |a_i - b_i|,b_i)\) 的线段。而每个保安就是一个起点为 \((p_i,x_i)\) 每次可能会向右上或者右下走。那么保安和用户一起走的时间就是这两条线段重合的路程。
此时你发现所有线段要么是和 \(y = x\) 平行的,要么是和 \(y = x\) 垂直的。那么考虑把整个坐标系旋转 \(45^\circ\),即 \((x,y)\) 变成 \((x - y,x + y)\)。那么此时所有的线段的长度都是原本的 \(2\) 倍,那么此时一个保镖获得的报酬就是一起走的路程 \(L\) 再乘上 \(\frac{c_i}{2}\)。
由于 \(n\) 很小所以考虑把用户线段的起点和结尾作为关键点离散化一下,得到 \(\mathrm O(n^2)\) 个节点。然后对于每个节点考虑处理出当每个保镖走到这里之后可以获得的最大收益是多少。然后到格点前的最大价值可以使用李超线段树维护。
T9. P7723
待补。
T10. P11149
待补。
T11. CF1889D
待补。
T12. P8114
待补。
T13. P7451
待补。
T14. qoj6344
待补。
T15. P2599
待补。
T16. P9535
待补。
T17. qoj15304
待补。
T18. CF1508C
待补。
T19. P7247
待补。

浙公网安备 33010602011771号