CDQ分治学习笔记

CDQ 分治

其实CDQ本质就类似线段树,\(i\)的贡献由\(1\)\(i-1\)在线段树上拆出的log个节点组成,然后将可以被同一段区间做贡献的点一起计算从而保证复杂度。

例题:

P3810 【模板】三维偏序(陌上花开)

题意:对于\(k\in[1,n]\)求三维偏序数量为\(k\)的点的个数。

思路:其实就是求每个点的三维偏序数量,可以考虑先按一维排序,然后就只用求二维偏序数量,然后就可以直接CDQ了。

具体来说,先递归处理左右区间,然后考虑计算\([l,mid]\)\([mid+1,r]\)的贡献。分别将\([l,mid],[mid+1,r]\)按一维排序,然后用双指针保证此时\([l,j]\)的第一维小于当前计算的点,然后用树状数组维护第二维有多少点,直接查询即可。操作完要把树状数组上的操作撤回。复杂度\(O(n\log^2n)\)

P3157 [CQOI2011]动态逆序对

题意:给定一个排列,每次会删掉一个点,求每次删前的逆序对个数。

思路:发现每个点对\((i,j)\)会做贡献当且仅当\(t_i<t_j,p_i<p_j,pos_i>pos_j\)\(t_i<t_j,p_i>p_j,pos_i<pos_j\),发现这可以直接三维偏序解决。

复杂度:\(O(n\log^2n)\)

P4169 [Violet]天使玩偶/SJY摆棋子

题意:动态加点和查询与一个点曼哈顿距离最近的点的距离是多少。

思路:考虑把\(dis(A,B)=|A_x-B_x|+|A_y-B_y|\)的绝对值拆开,其实本质就是把每个点左下、左上、右上、右下四个部分分开来讨论,然后就转化成了求\(\min\limits_{x_j<x_i,y_j<y_i}(x_i+y_i-(x_j+y_j))\),直接用CDQ即可。发现第三维求的是前缀的max,可以用树状数组减小常数。

[SDOI2011]拦截导弹

题意:求最长二元不上升子序列长度和每个点处在最长上升子序列中的概率。

思路:考虑朴素DP,设\(f1_i\)表示以\(i\)结尾的最长二元上升子序列长度,\(g1_i\)为其数量,\(f2_i\)\(g2_i\)表示以\(i\)开头,那么\(\max f1_i\)为第一问答案,\([f1_i+f2_i-1=maxn]\dfrac{g1_i\times g2_i}{sum}\)为第二问答案,其中\(maxn=\max f1_i,sum=\sum g1_i\)。可是直接这样做是\(O(n^2)\)的,我们考虑用CDQ优化。考虑\([l,mid]\)\([mid+1,r]\)的贡献,用数据结构维护出当前最大的\(f1_i,g1_i\),然后直接查询最大值更新答案即可。

P4390 [BalkanOI2007] Mokia 摩基亚

题意:矩形加,查询矩形和。

思路:把询问差分一下就是普通三维偏序了,直接套板子即可。

P3658 [USACO17FEB]Why Did the Cow Cross the Road III P

题意:给出两个排列 \(A,B\) ,相等的数之间连线,求数对 \((i,j)\) 的个数。其中 \((i,j)\) 满足:它们所在两个排列间对应的线交叉且 \(\mid i-j\mid>k\)

思路:(一开始把题目看错了,知道交上去WA了才发现)也是裸的三维偏序,只是第三维查询是注意一下即可。

CF848C Goodbye Souvenir

题意:单点改,求区间内出现过的数最后一次出现的时间减去第一次出现的时间之和。

思路:(最开始一直不知道怎么转化,知道怎么转化后发现此时很简单)。我们求出每个点的前驱,记为\(pre_i\),那么问题就是求所有满足\(i\in[l,r],pre_i\in[0,l)\)\(i-pre_i\)之和,于是用set来维护一下前驱后继,就可以直接三维偏序求解。

P5621 [DBOI2019]德丽莎世界第一可爱

题意:求四维权值最大不降链。

思路:发现比三维偏序多了一维,于是考虑CDQ套CDQ。先整体按第一维排序,然后还是考虑\([l,mid]\)\([mid+1,r]\)的贡献,这又是一个三维偏序问题,于是把\([l,mid]\)的点标记一下,再对\([l,r]\)进行一次CDQ,之后再还原即可。

P3206 [HNOI2010] 城市建设

题意:带修改边权的最小生成树。

思路:CDQ 分治神题。

考虑对时间进行分治。假设当前考虑到区间 \([l,r]\),我们把边分成两种,一种是没有修改的静态边,一种是动态边,此时可以先处理静态边。有一些静态边没有其他的静态边优,那么以后也不会再使用,同时会有一些静态边连接动态边连通块,那么这些静态边一定会在 MST 中,于是我们就要删掉不会再出现的边,然后把一定会加入的边在静态边集中缩点。可以证明此时剩下的静态边和动态边的数量大致相等。

考虑怎么将 \([l,r]\) 分成 \([l,mid]\)\([mid+1,r]\)。这里就是简单的将 \([mid+1,r]\) 中没有修改的边当成 \([l,mid]\) 中的静态边,反过来同理。对于最后一条动态边,修改权值然后更新答案即可。

复杂度 \(O(n\log^2n)\)

「JOISC 2014 Day3」稻草人

题意:平面上有 \(n\) 个稻草人,求有多少个和坐标轴平行的长方形满足左上角和右下角是稻草人且内部(不含边界)没有稻草人。

思路:考虑 CDQ 分治,那么此时我们要统计的就是左下角在 \([l,mid]\),右上角在 \([mid+1,r]\) 的矩形个数,考虑按 \(y\) 从大到小加入左侧点,维护 \(x\) 递减的单调栈,这样可以求出以这个点为左下角的矩形的纵坐标上界,然后再右边维护横坐标递增的单调栈,就可以求出答案了。

posted @ 2024-02-13 10:13  Xttttr  阅读(20)  评论(0编辑  收藏  举报