7.23 做题记录

发布时间 2023-07-23 21:51:28作者: Rain__Song

P3897 [湖南集训] Crazy Rabbit

考虑一个点到圆的两个切点构成的圆弧,如果两个点连线与圆不交,那么两端圆弧是相交但不包含的,且把一段圆弧取反不影响答案。

断环成链,原问题等价于选最多的区间 \((l,r)\) 满足对于所有 \(i <j\)\(l_j < r_i\) 枚举起始区间做 LCS 即可,时间复杂度 \(O(n^2 \log n)\)

总结:

  • 利用投影描述复杂信息

P5906 【模板】回滚莫队&不删除莫队

在普通莫队中增加是容易的,删除较为困难,考虑如何避免删除。

对于左端点所属块相同的询问,我们按右端点排序,先处理出右边的前缀信息,每次把 \(l\) 指针拉到左端点所属块的右端,暴力修改信息,这样每次询问只需要左移 \(l\),可以分析出复杂度为 \(O(q \log n)\)

总结:

  • 花费一定的代价把问题转化为熟知的,可做的形式

P5986 [PA2019] Szprotki i szczupaki

首先每次必然会选择小于 \(x\) 最大的数,且每次操作后如果不能大于 \(k\) 或者大于 \(x\) 最小的数,就失败了。

使用线段树维护数集,每两次操作后的大小必然大于第一次选择的数的两倍,时间复杂度 \(O(n \log n \log V)\)

总结:

  • 注意题目中自然的 \(\log\)

P4769 [NOI2018] 冒泡排序

通过一些简单的情况可以发现,排列中不存在长度 \(\geq 3\) 的下降子序列,由 Dilworth 引理这等价于可以划分成两个上升子序列。

\(f_{i, j}\) 为前 \(i\) 个的最大值为 \(j\) 后面 \(n - i\) 个位置的方案数,则:

\[ f_{i, j} = \sum_{k = j}^n f_{i + 1, k}\]

考虑其组合意义,即从点 \(A(i, j)\) 走到 \(B(n, n)\) 的不与直线 \(y = x - 1\) 相交的方案数。

不考虑后者,答案为 \(\dbinom{n-i-1}{2n - i - j - 1}\),考虑第一个相交的位置,经过直线的方案数即为从点 \((j + 1, i - 1)\) 出发到点 \((n, n)\) 的方案数,于是 \(f_{i,j} = \dbinom{n - i - 1}{2n - i - j - 1} - \dbinom{n - j - 2}{2n - i - j - 1}\)

现在有字典序的限制,钦定一段前缀相同,可以得到最终答案为从 \((i,\max\limits_{j\leq i}q_j+1)\) 游走到 \(n,n\),而且不走到线以上的方案数,类似地可以求,时间复杂度 \(O(\sum n)\)

总结:

  • 对于一个严格的限制(即不满足是容易的),一般其补集会有一个简单的判断,可以通过一些局部 / 边界情况来得到
  • 字典序比较钦定前缀

P5537 【XR-3】系统设计

考虑 \(rt \to x\) 路径唯一,记为 \(p_x\),考虑将 1 操作转化为由根节点开始,并将 \(p_x\) 接入 \(a_{[l, r]}\) 前,二分结束位置,问题变为查询一序列是否属于 \(p\)、在 \(p\) 中位置。
考虑哈希。利用线段树可将 2 操作变为线段树上单点修改区间,时间复杂度 \(O(n + m + q \log^2 m)\)

总结:

  • 利用 Hash 处理一一对应的序列匹配问题

CF1641D Two Arrays

注意到 \(m\) 的范围很小,这启发我们在复杂度上带上一些 \(2^m\) 状的东西。

先做双指针,现在要计算当前是否存在不交的数组对。

写出数组 \(X,Y\) 的幂集 \(P_x,P_y\),考察以下式子

\[\sum_{x\in P_x}\sum_{y\in P_y}[x=y](-1)^{|x|-1} \]

它在 \(P_x, P_y\) 有交集时为 \(0\),否则为 \(1\)

使用 Hash 维护幂集,在双指针的过程中记录桶判断,时间复杂度 \(O(nm 2^m)\)

总结:

  • 范围很小的集合相交问题,考察其幂集