2024.7 #4 华夏风华 琢一番飞扬 待得开拓封疆 济沧桑 游目聘怀森森万象 沥肝胆 披阅九州的 风光

华夏风华 琢一番飞扬
待得开拓封疆 济沧桑
游目聘怀森森万象 沥肝胆
披阅九州的 风光


1. P7470 [NOI Online 2021 提高组] 岛屿探险

我们可以发现这个东西可以拆成很多个子问题,然后累计合并,这个东西可以使用线段树合并来做。

先考虑 \(b_i > d_j\) 的情况。那么答案就是 \(\sum [a_i \oplus c_j \le d_j]\)。我们把 \(a_i\) 插入 \(01 \text{trie}\) 中。然后我们从上往下走,走到深度为 \(h\) 的节点,那么代表他的值等于 \(c_i \oplus d_j\) 的前 \(h\) 位。然后我们考虑第 \(h + 1\) 位。

  • \(d_i = 0\),那么 \(a_i\)\(c_j\) 的第 \(h + 1\) 位必须相等,否则 \(a_i \oplus c_j > d_j\),然后直接往这个方向走即可。

  • \(d_i = 1\),那么此时 \(a_i\)\(c_j\) 的第 \(h + 1\) 位任意取都行。那么就有两种可能:

    • 如果 \(a_i\)\(c_j\) 的第 \(h + 1\) 位不一样,那么此时 \(a_i\) 依然等于 \(c_j \oplus d_j\),所以我们向这个方向继续走即可。
    • 如果 \(a_i\)\(c_j\) 的第 \(h + 1\) 位一样,那么此时 \(a_i \oplus c_j\) 就会一定小于 \(d_j\) 了,那么对于答案的贡献就是这个子树里 \(a_i\) 的个数之和。

这一部分就是 CF817E。比较简单。

接下来我们考虑 \(b_i \le d_j\) 的情况。这一个部分比较困难。但是我们发现这一个部分和 \(a_i \oplus c_j \le d_j\) 的结构很像,所以我们可以考虑类似的操作。

前面的是对于 \(a_i\) 扔到 \(01 \text{trie}\) 上然后查询 \((c_j,d_j)\),那么我们这次就可以把 \(c_j\) 扔到 \(01 \text{trie}\) 上,然后记录每一个 \((a_i,b_i)\) 对于 \(c_j\) 的贡献。

具体的我们只需要把 \(c_j\) 离线下来,然后对于 \((a_i,b_i)\) 查询,但是唯一的区别就是在上面我们遇到了一个节点满足 \(a_i \oplus c_j < d_j\) 时我们加上的是子树里 \(a_i\) 的个数和,而现在我们要在这一个子树打一个标记,让整一个子树全部都加上 \(1\),然后统计答案是就是从根到 \(c_j\) 路径上的标记和。

当然我们不能每一次都建 \(2\)\(01 \text{trie}\),但是那样子的复杂度爆炸,无法接受。

然后我们考虑如何优雅的计算多组数据。

首先我们将 \((a_i,b_i)\)\((c_j,d_j)\) 按照 \(b_i,d_j\) 升序排列。然后那双指针进行维护。此时我们开两个 \(01 \text{trie}\)。然后当我们扫到了第 \(j\) 个问题不满足 \(b_j > d_j\)\(a_i\) 从维护第一个 \(01 \text{trie}\) 中删除,然后计算贡献。同时对于满足条件的 \((a_i,b_i)\) 加入维护第二个情况的 \(01 \text{trie}\) 上并且计算贡献。

当然此时两个指针都往右移动。


2.Magic Breeding

我们先考虑特殊情况 \(a_i \in \{0,1\}\)。那么此时我们可以吧每一列看成一个 \(01\) 串,而这种串至多有 \(2^k\) 个。

然后我们发现取 \(\max\) 和两行取或一样,取 \(\min\) 和两行取与一样,那么两个初始一样的两列在经过若干操作后还是一样,那么我们扔一个 bitset 的来维护这些序列。

那么我们要怎把 \(a_i\) 都变成 \(\{0,1,\}\)。我们对于每一列都离散化,让值域都在 \([1,k]\) 之间。然后将这一列每 \(x\) 个数都拆成 \(k\)\(\{0,1\}\)。其中的前 \(x\) 个数为 \(1\),剩下的数
\(0\)。那么最终的时间复杂度为 \(O(\dfrac{q \times 2^k}{w})\)


3.P5114 八月脸

截图选老婆

我们发现答案的形式是 \(ka + b\),这个东西可以使用凸包维护。然后我们发现询问的答案和树上的路径有关,可以想到用点分治维护。

然后再点分治的过程中记录每一个点到根节点的点权和为 \(a_x,b_x\)。对于每一个根的每一个子树,我们都维护黑点和白点的凸包,那么答案就是这两个凸包的闵可夫斯基和。然后我们有三种维护方法。

  1. 先不考虑两个点在同一棵子树的情况计算最后再容斥掉。
  2. 逐子树加入,即考虑每棵子树对之前加入的子树的贡献。
  3. 利用合并果子,每次取出 size 最小的两个凸包,然后把两个合并起来。那么复杂度是 \(\log\) 的。

明显的,前两种的维护都十分复杂,我们在此选择第三种。然后求出最终的凸包后直接二分求出最大值即可。

posted @ 2024-07-30 07:59  sqrtqwq  阅读(9)  评论(1编辑  收藏  举报