例0
u 二维平面上有一些点。有Q个询问,每个询问问横坐标不超过x,纵坐标不超过y的点的数目。可以离线。
u 这题的另一种形式是求逆序对。
u 正解:把所有点和询问排序,然后用树状数组即可求解。
例1
u 在一个初始为空的二维平面上,要求支持2种操作:
u 插入一个点
u 查询一个矩形内点的个数
u 坐标<=2*10^6
u 操作1数量<=160000
u 操作2数量<=10000
u 问题可以转化为:给定一个三维平面,每次求三维坐标在一个范围内的点的个数。
u 按x排序,然后考虑分治。
u 两边内部的答案可以递归计算。我们需要计算左边的点对右边的询问的贡献。
u 分别处理两边后,我们可以把左右按y排序,依次处理。对于x在左半边的点,按z坐标插入树状数组中,这样我们就可以快速统计出x在右半边的询问的答案了。
u 排序可以用归并来完成。
u 时间复杂度:O(nlog^2n)
u 这个算法是由cdq提出的,所以叫cdq分治。
例2
u 给定二维平面上的n个点,求最近点对
u n<=10^5
u 考虑分治。
u 按x坐标排序,然后先求出左边一半和右边一半的解。
u 假设当前答案为d,那么找出距离中线(mid)小于d的点。
u 将这些点按y坐标排序。对于每个点,只需要求它和它上面8个点的距离并更新答案即可。
u 想一想,为什么?
u 事实上,这个数字还可以缩小。有兴趣的同学可以自行思考。
例5
u N个物品有单价,收益,限购次数,第i个询问用w[i]的钱,在禁止购买ban[i]的情况下,能获得的最大收益
u N<=1000 Q<=10^6 w[i]<=1000
u 考虑分治
u 对于全部的物品,对于右边一半的物品,左边一半的物品都对它有贡献
u solve(l,r)表示,当前维护dp数组,记录的答案是出去[l,r]外的物品的答案
u solve(l,mid)时用[mid+1,r]内的物品转移dp数组
u 当l=r时,将所有ban=l=r的询问一起(查dp数组)求答案
u 给定一张无向图(n<=700),每条边都有两个边权A和B
u 求一棵生成树,使得(所有边的A边权之和)*(所有边的B之和最小)
u 最小乘积模型:
u 考虑用二维平面上的点表示每一个解,其中x坐标表示其中一维权值和,y坐标表示其中另一维权值和。
u 每一个解对应的答案即为该点所在的反比例函数的k值。
u 很显然,最优解一定在凸壳上。
u 分治地去求这个凸壳。先求出x最小的解L,y最小的解R。
u 找到离AB这条直线最远(靠近原点方向)的解Mid。(想一想,怎么求?)
u 然后不停地分治,直到Mid离AB的距离为0。
u 每次求出一个新解时,就更新答案。
u 复杂度:玄学(n不大不小)
例1 cogs1752
例2 hdu1007
例5 bzoj3163
例6 bzoj2395