分治相关

朴素分治

对于一维序列上或二维平面上需要计算和路径等相关问题时,可以按照类似点分治的思路每次选择中点,然后计算跨过中点的价值,递归处理时时间复杂度是 \(log\) 级别的

一些一维或者二维的经典题:


B. 第负一题
题解

可以发现分治转化的作用在于分成左右两边后可以很方便地分别进行公式转化从而配对求解


P3350 [ZJOI2016]旅行者

这个很显然属于路径类问题,且答案具有可合并性,具有可拆分性,即最短路不会折返过中线,那么直接将平面分成两半分别跑最短路即可
一个很好的剪枝是类似于 \(k-d\) 树的构建,即对折交替进行


CF232E Quick Tortoise

由于只能向右下行进,问题满足了所有性质
于是分治后开始 \(dp\) 即可,设 \(f[i][j][k]\) 表示从 \((i,j)\) 出发能否到 \((mid,k)\)
发现所有转移最后一维是不变的,于是用 \(bitset\) 优化转移即可


CF364E Empty Rectangles

一样的,考虑折半行,合并关于列的答案
枚举列的两个端点,计算出此时上下边界的最值,可以发现行的合法范围是单调进行的,于是指针扫一下即可


线段树分治

线段树分治用于维护只方便插入不方便删除的结构,比如并查集,线性基等


P4585 [FJOI2015]火星商店问题

对时间建立分治的线段树,然后把询问和操作到挂在线段树上
对于每一个节点都分别建立可持久化 \(trie\) 树后进行查询,复杂度是正确的


CF576E Painting Edges

可以发现此时每条边存在的时长不确定,但是线段树是可以先递归进去查合法性的,于是搜到叶子结点后回溯后动态执行删除任务即可
具体地,对于每一个区间待修改的所有边直接赋为上一种颜色,递归到叶子结点后动态维护当前颜色,回溯时一律撤销
此时复杂度正确的保证是修改都是单点的


整体二分

如果对于多个询问都需要二分答案,并且没有依赖性,那么可以放在一起采用分治的方式进行整体的二分
多用于第 \(k\) 大问题


P2617 Dynamic Rankings

这个是最基础的操作,来讲一下流程
取当前值域中点 \(mid\),对于所有所有小于这个值的修改按次进行,询问直接询问区间和
对于修改,值小于 \(mid\) 的放左边,对于查询,答案小于 \(mid\) 的放左边,递归进行即可


P4175 [CTSC2008]网络管理

把这一过程放到了树上,直接改成树剖即可


P3242 [HNOI2015] 接水果

首先把包含关系刻画为一系列 \(dfs\) 序的大小关系
首先列式子:

  • 如果不是一条链,那么此时 \((x,y)\) 两个点一定在这两个点分别的子树里。那么需要满足 \(l_u\le l_x\le r_u,l_v\le l_y\le r_v\)
  • 如果是一条链,则一个在子树内一个在子树外,根据子树外的情况再次分类(设 \(z\) 表示 \(v\)\(u\) 路径上最后一个点):
    • \(1\le l_x\le l_z-1,l_v\le l_y\le r_v\)
    • \(r_z+1\le l_x \le n,l_v\le l_y\le r_v\)

此时就可以转化成二维偏序问题了
如果更直观一点,可以观察发现可以直接把 \(l_x,l_y\) 看成一个点,于是变成了扫描线问题

posted @ 2022-08-26 19:59  y_cx  阅读(32)  评论(0编辑  收藏  举报