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

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


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

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

先考虑 bi>dj 的情况。那么答案就是 [aicjdj]。我们把 ai 插入 01trie 中。然后我们从上往下走,走到深度为 h 的节点,那么代表他的值等于 cidj 的前 h 位。然后我们考虑第 h+1 位。

  • di=0,那么 aicj 的第 h+1 位必须相等,否则 aicj>dj,然后直接往这个方向走即可。

  • di=1,那么此时 aicj 的第 h+1 位任意取都行。那么就有两种可能:

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

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

接下来我们考虑 bidj 的情况。这一个部分比较困难。但是我们发现这一个部分和 aicjdj 的结构很像,所以我们可以考虑类似的操作。

前面的是对于 ai 扔到 01trie 上然后查询 (cj,dj),那么我们这次就可以把 cj 扔到 01trie 上,然后记录每一个 (ai,bi) 对于 cj 的贡献。

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

当然我们不能每一次都建 201trie,但是那样子的复杂度爆炸,无法接受。

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

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

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


2.Magic Breeding

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

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

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


3.P5114 八月脸

截图选老婆

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

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

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

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

posted @   sqrtqwq  阅读(11)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示