整体二分
整体二分类似于线段树上二分,在讲这个算法前,先引入几个问题。 解决题型 整体二分一般解决的是如下的问题: 给你一个【集合/序列/矩阵/树】,要求【静态/动态】维护所有【元素/区间/子矩阵/链/子树】中的第 $k$【可能每次给定】大元素,【可能强制在线】。 下面是一堆例题。 例题1 动态查询集合第k大(可离线) 题意 让你维护一个初始为空的多重集合 $s$,并支持 $q$ 次操作,操作都是下面三种之一: 添加一个数 $x$ 到集合 $s$ 中。 在集合 $s$ 中删除一个数 $x$(保证元素存在)。 查询集合第 $k$ 大(保证第 $k$ 大存在)。 数据范围 $1 \leq q \leq 2 \times 10^5$ $0 \leq x \leq 10^9$ 题解 维护一个权值线段树(权值线段树其实就是一个维护值域的线段树),维护一段值域里有多少个数,每次询问在线段树上二分即可。 具体地,对于线段树上某个节点对应的区间 $[l,r]$,这个节点上的值为集合中,值在 $[l,r]$ 的数的个数有多少。 在询问时,我们要记录当前节点编号 $x$,$x$ 维护区间 $[l,r]$,以及要查询值在 $[l,r]$ 内的所有数的第 $k$ 大。 当递归到某个状态后,我们看这个节点的左子树 $\text{lc}$ 内有多少个值,如果大于等于 $k$,则递归到左子树;否则递归到右子树,且 $k$ 减去(左子树内数的个数)。 由于值域较大,权值线段树可能会爆,所以要先把所有询问离线下来,做个离散化,然后就可以把 $x$ 控制到 $q$ 级别,就不会爆了。 ...