2022.12.4 闲话

操作独立数据结构题的一些套路:

操作分为修改,查询 .

操作独立:如果段内没有查询,则乱序排列修改后结果不变 .

允许离线 / 强制在线:略 .

一些策略:

  • 时间分治(时间分块 / 二分时间 / CDQ 分治)
  • 二进制分组
  • 整体二分

大概是二分时间的一道题:

共点圆

维护一个平面,支持:

  • 给一个点,加一个圆心位于该点且过原点的圆 .
  • 给一个点,查询这个点是否在所有圆的内部 .

为了方便,保证所有点都在 \(x\) 轴上方且横坐标非 \(0\) .

根据观察可以发现,一个点 \((x,y)\) 位于以 \((x_0,y_0)\) 为圆心且过原点的圆内当且仅当 \((x,y)\) 位于半平面 \(2x_0x+2y_0y\ge x_0^2+y_0^2\) 内 .

于是问题可以变成加点,查所有点是否都在给定半平面内 .

显然操作独立,于是对时间二分一下, 就变成没有修改的问题了 .

显然凸包上二分一下就 2log 了 .

凸包斜率排序,合并时归并即可 1log .

若静态问题可以在 \(f(n)\) 时间内解决,则操作独立,允许离线的动态问题采用对时间二分的策略时间复杂度仅多一个 log,具体的,时间复杂度为

\[T(n)=2T\left(\dfrac n2\right)+f(n) \]

解出来就是 \(T(n)=O(f(n)\log n)\),一般都是对的 .

CDQ 分治也是一样的,比如:

半平面交

维护半平面集合,支持:

  • 加一个半平面 .
  • 删一个半平面 .
  • 查一个点是否在它们的交内 .

CDQ 分治,只需要处理前面的删除对后面的影响 .

这个就只需要维护一个删半平面和查询的数据结构即可 .

时间倒流就变成加半平面然后查 .

这个时间分治即可 .

经过若干套娃之后我们就得到一个 3log 的诡异做法 . 也可以类似做到 2log,略 .


时间分块的话有点邪门,链个 joke3579:操作分块 .


二进制分组

这个似乎是 well-known 技术了,简要说一下 .

比如要维护一个集合支持一些东西,不过静态很平凡,咋做呢 .

考虑初始维护一个只有一个元素的集合,加一个元素就把它对应的集合扔到末尾,如果最后两个集合大小相同就暴力合并 .

显然根据一些均摊分析,只贡献一个 log,而且是在线的 .

不均摊的话也可以爆算,不过不太优美:

设建立静态数据结构的时间复杂度是 \(f(n)\),询问是 \(g(n)\) .

则暴力重构的总时间复杂度就是

\[\begin{aligned}\sum_{k=1}^nf(\operatorname{lowbit}(k))&=\sum_{i=1}^{\lfloor\log n\rfloor}\left\lfloor\dfrac n{2^{i+1}}+0.5\right\rfloor f(2^i)\\&\le\sum_{i=1}^{\lfloor\log n\rfloor}f(n)\\&=\Theta(f(n)\log n)\end{aligned} \]

这样重构的时间复杂度就是 \(O(f(n)\log n)\) .

自然想到能否 \(k\) 进制分组 .

具体描述一下,其实就是二进制分组直接扩展:考虑初始维护一个只有一个元素的集合,加一个元素就把它对应的集合扔到末尾,如果最后 \(k\) 个集合大小相同就暴力合并 .

类似 \(k\) 叉树状数组,其实就是把修改和查询的复杂度改了一下,渐进还是 1log .

具体分析可以魔改一下上面那个爆算做法 .


整体二分

加一个 log 实现全局二分 .

不说了,因为我不太会 .

posted @ 2022-12-04 18:15  Jijidawang  阅读(47)  评论(0编辑  收藏  举报
😅​