【学习笔记】 CDQ 分治,WQS 二分

CDQ 分治

我们把一个区间 \([l,r]\) 分成两部分 \([l,mid],[mid+1,r]\),递归下去分治,然后考虑 \([l,mid]\)\([mid+1,r]\) 答案的贡献,累加上去再递归的去求 \([mid+1,r]\) 的答案。

如果每次计算贡献复杂度是 \(O(f(len))\) 的,那么我们的整体的复杂度就是 \(O(f(n)\log n)\) 的。

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

三维偏序的板子,我们首先考虑如果是二维偏序怎么做,很简单就是排序然后一个权值线段树。

我们先对原本的区间排序然后离散化,开始分治,分治的时候我们对分出来的小区间按照 b 排序,此时原本的性质依然被保持。然后我们用双指针维护,套一个树状数组即可。

inline void CDQ(int l,int r){
	if(l==r) return; CDQ(l,mid(l,r));CDQ(mid(l,r)+1,r);
	sort(a+l,a+1+mid(l,r));sort(a+mid(l,r)+1,a+r+1);
	int pl=l,pr=mid(l,r)+1; while(pr<=r){
	while(pl<=mid(l,r) && a[pl].first <= a[pr].first) {Add(val(pl),num(pl));++pl;}
	ans(pr)+=Query(val(pr));++pr;}  
	for_(i,l,pl-1) {Add(val(i),-num(i));} return;
}

P8575 「DTOI-2」星之河

我们容易想到把红和蓝抽象为二维偏序,然后我们发现其实是还有一个 dfn 相关的限制的,所以再把 dfn 形象化一下就是 \(dfn_u<dfn_{x}<dfn_{u+siz_u}\),一眼看好像是个类似四维偏序的东西,但是可以扔到树状数组上面差分一下,然后就变成了三维偏序,直接 CDQ 即可。

WQS 二分/决策单调性分治

我们现在拿到一个选物品的限制条件,要求刚好选 \(k\) 个,最大化/最小化权值。如果只有这个条件我们显然可以直接贪心,但是如果收益不清晰我们就会自然而然的想到 \(dp\),使 \(dp_{i,j}\) 表示前 \(i\) 个物品选 \(j\) 个物品的权值,转移方程是 \(dp_{i,j}=\max\{dp_{i-1,j-1}+w_{i},dp_{i-1}{j}\}\)。复杂度是 \(O(n^2)\) 的,显然很菜。

容易发现我们如果没有这个选 \(k\) 个的限制就很好做了,我们考虑把这个条件去掉。考虑一个决策点 \(g(i)\) 表示取 \(k\) 个物品时的最大收益,很容易想到我们会先去取那些收益大的,所以容易发现 \(g(i)-g(i-1)≥g(i+1)-g(i)\),或者说增加一个物品的收益单调不增。

那么我们就知道对于 \(g(x)\) 是一个上凸包,我们要求出来的就是 \(g(k)\),我们可以发现这个上凸包的斜率是单调不降的,注意到单调性,容易想到我们对斜率进行二分,假设我们现在的斜率是 \(k\),那么我们让这个切在点 \(x\) 上,此时 \(g(x)=kx+b\),可以算出 \(b=g(x)-kx\),也就是截距为 \(g(x)-kx\),但是这个切的直线是我们没有固定选多少个的情况,我们拿到这个截距 \(b\) 之后每选一个就减去一个 \(k\) 即可。

P2619 [国家集训队] Tree I

容易想到我们先构造一个全都是黑色边的 MST,然后考虑往里头添加白色边,我们肯定是尽可能用小的白色边去代替加入后构成的环上的最长的黑色边,可以发现每次增加后的斜率单调不降,所以考虑 WQS 二分。我们给所有白色的边加上一个 \(w\),然后跑最小生成树判断里头的 \(k\) 是多少暴力判断能不能行即可。

P3045 [USACO12FEB] Cow Coupons G

抛弃脑子,注意到 \(k\) 的限制,想想能不能 WQS 二分,我们显然能求出来买 \(x\) 个奶牛用 \(k\) 个优惠卷的最少花费,容易想到用优惠卷减去的价格越来越少,有单调性,直接大力 WQS 二分,然后外侧一个二分答案即可。

posted @ 2025-12-05 10:39  Vsinger_洛天依  阅读(2)  评论(0)    收藏  举报