AIGC标识 QOJ-5500 条形:从广义斜率优化到共同支配

从决策树到永久支配引理——QOJ 5500 的另一种理解

写在前面:本文核心证明较大部分由 AI 生成,人工核验。其余部分为人工。

模拟赛考了这道题,众所周知我一直不会建模和最优子结构,果断地列 dp 式,果断地瞪能否优化,果断地挂掉了。

下课后,我和一位超越凡俗的存在(GPT 6.0-Ast)彻夜长谈,于梦中灵光乍现,想到了一些好玩的东西。

题面

有一个数轴,上有 \(n\) 个点 $ [1,n] $,每个点有一个点权 \(p_i\)。

你可以从这 \(n\) 个点中选择任意数量的点。比如说你选的点集合为 \(S\),那么对于每个点 $i \in[1,n] $,如果它左边最接近的(特殊地,不包括自己)被选择的点为 \(L\)(即 $max_{j\in S, j<i} j $ ),右边最接近的(也不包括自己)被选择的点为 \(R\)(即 $min_{j\in S, i<j} j $),那么它将提供 $p_L+p_R $ 的贡献。

正解

很唐啊,很唐。但我没看出来

注意到,相邻的被选择的两点 \(i,j\) 之间这一段的贡献为 $ (p_i+p_j)\times(i-j) $,看起来很像一个矩形。劈一半就是 $ (i,p_i),(j,p_j) $ 两点围成的梯形。由此发现维护凸包直接做即可。复杂度 $ O(n) $。

LL p[N];
LL f[N];
int stk[N],top;

void zako_problem()
{
	read(n);
	For(i,1,n) read(p[i]);
	top=0;
	stk[++top]=1;
	For(i,2,n){
		while(top>1&&(p[i]-p[stk[top]])*(stk[top]-stk[top-1])
		    >=(p[stk[top]]-p[stk[top-1]])*(i-stk[top])) top--;
		int j=stk[top];
		f[i]=f[j]+(i-j)*(p[i]+p[j]);
		stk[++top]=i;
	}
	printf("%lld\n",f[n]);
}

但是,真的就只能这样吗?

不妨考虑 dp

手玩一下两项之间插入一个东西会发生什么,得到了一个形如 $ ip_j-jp_i $ 的式子。列一下转移:

定义 \(f_i\) 为转移到 \(i\) 时的原答案,定义 $ g_i=f_i-ip_i $,有转移 $ g_i=max_{j<i} { g_j+ip_j-jp_i } $。

你获得了一个 \(O(n^2)\) 的 dp!

发现斜率

考虑优化。直觉上这个东西其实长得很决策单调性或斜率优化。但是往这些方向想了想感觉不是很对。怎么办呢?

思考一下,究竟何为决策单调性?不论是常规的决策单调性还是斜率优化,都是存在某种支配关系,使得一旦 \(i\) 被使用,那么他将永远支配一堆其他的决策,使其可以被永久删除。

那我们从决策来考虑。

不妨记 \(w(i,j)=jp_i-ip_j\)。

定义 $ T_i(j) $ 表示 \(i\) 从 \(j\) 转移得到的值,即 $ T_i(j)=g_j+w(j,i) $。

加入我们已有对于 \(b\),$a\rightarrow b $ 是最优的,假如说一个 \(c\) 满足了 $ a\rightarrow b\rightarrow c < a\rightarrow c $,考虑发生了什么。

\(g_b=g_a+w(a,b)\)

\(T_c(a)=g_a+w(a,c)\)

\(T_c(b)=g_b+w(b,c)=g_a+w(a,b)+w(b,c)\)

若 \(T_c(a)>T_c(b)>0\),有 \(w(a,c)-w(a,b)-w(b,c)=w(a,c)+w(c,b)+w(b,a)>0\)。

式子展开。

\[\begin{aligned} \textnormal{原式} &=cp_a-ap_c+bp_c-cp_b+ap_b-bp_a\\ &=p_a(c-b)-p_b(c-a)+p_c(b-a)\\ &=p_a(c-b)-p_b(c-b)-p_b(b-a)+p_c(b-a)\\ &=(b-a)(p_c-p_b)-(c-b)(p_b-p_a)\\ &=(c-b)(b-a)(\frac{p_c-p_b}{c-b}-\frac{p_b-p_a}{b-a}) >0. \end{aligned} \]

注意到 \((c-b)(b-a)>0\),所以原式即 \((\frac{p_c-p_b}{c-b} > \frac{p_b-p_a}{b-a})\)

经过简单转化,我们发现,这就等价于,一条决策链上满足相邻的 \((i,p_i)\) 斜率递减吗,标准凸包定义。

我们发现,似乎固定 \((i,p_i)\) 后,我们所求就是前面所有 \((j,p_j)(j<i)\) 的点形成的凸包与 \((i,p_i)\) 形成的最小斜率的直线。换句话说,直接拿一条过 \((i,p_i)\) 的直线去切凸包即可。

这也就是我们的广义斜率优化。到此为止可以做到 \(O(n\log n)\) 在凸包上二分斜率找最优决策。

所以,我们,做完了……吗?

等等!这个式子满足仅当 \(a\rightarrow b\),如果不满足这个就不可以了!比如说对于 \(a,b\) 满足 \(x\rightarrow a,y\rightarrow b\),那 \(g_a,g_b\) 将没有任何关系,这个式子也不再适用。

恭喜,我们完蛋啦!

决策结构&永久删除引理

我们都知道,普通的斜率优化有一点决策单调性的影子。那么在本题,能否找到决策单调性呢?

考虑本题中,决策是什么样子的。

定义 \(pre(i)\) 表示 \(i\) 的决策点,不难发现这会形成一个决策树,这对于所有决策类题目是通用的。发现这恰为我们的 $ pre(i) \rightarrow i$ 的连边。为了方便我们仍旧使用 \(\rightarrow\) 表示。

本题中,由于我们只能处理一条“决策链”,即形如 $x_1\rightarrow x_2 \rightarrow x_3 \dots \rightarrow x_k $ 上的点,那我们先考虑一条决策链的变化。

当前正在考虑的点为 \(i\),分讨其决策类型(记 $K(x,y)=\frac{p_x-p_y}{x-y} $):

  • 若 \(c\) 的决策点恰为 \(i-1\),那直接将 \(i-1\) 接在后面链尾即可,这是最简单的情况。
  • 若 \(i\) 的决策为 \(i-1\) 的一个祖先 \(x\),根据前文的定义,不断往根走,应当有 \(K(i,i-1) > K(i,pre(i)) >\dots > K(i,x)\)。
  • 若 \(i\) 的决策不为 \(i-1\) 到根的一条链……那我们真的完蛋了。

但是,这真的可能发生吗?

在决策树上找到 \(x,i-1\) 的最近共同祖先,设为 \(l\)。有 \(l\rightarrow \dots \rightarrow i-1 ,l\rightarrow \dots \rightarrow x\)。不妨尝试简化问题:

拉回前文的 \(a,b,c\) 满足 $a\rightarrow b,a\rightarrow c $。显然 $l,i-1 $ 和 \(l,x\) 之间仍然满足斜率递增的关系,所以可以设 \(a=l\),\(b=x\),\(c=i-1\)。

(大概这样吧,感性理解一下 \(\rightarrow \dots \rightarrow\) 和 \(\rightarrow\) 在斜率的偏序关系上是等价的)

此时决策考虑 \(i\)。若 \(i\) 的决策为 \(b\),那存在 \(K(i,b)<K(i,c)\) 且 \(K(i,b)<K(i,a)\)。

推式子也能推出来这根本不可能,直接画图观察也不难发现这点:\(i\) 可能从 \(a\) 转移,也可能从 \(c\) 转移,但一定不会从 \(b\) 转移。

也就是说如果一个点 \(b\) 被后面的点淘汰掉了,那它将永远不会被作为候选点,\(b\) 就被永久删除了。

换句话说,\((a,c)\) 共同支配 了点 \(b\)。

现在我们可以正式定义共同支配这个概念了:如果存在三个决策 \(i,j,k\) 满足对于任意 \(x\) 均有 $ T_x(j)<T_x(i) \land T_x(j)<T_x(k) = \varnothing $,则称 \((i,k)\) 共同支配了 \(j\)。

当然,如果不感性理解的话,那就将视角调整为“从下往上链的叶子(或者说栈顶)被弹出时,被弹出的点将被共同支配”。

本题中,一旦一个点 \(i\) 的决策指向“当前维护的决策链的非叶结点”,那么它和它的决策 \(pre_i\) 将共同支配原决策链中的 \(pre_i\) 的儿子到原叶子这一串所有的点。

也就是说,对于节点 \(i+1\),至少存在一个可行的最优决策是决策树中 \(i\) 到根节点的链上的点。

Code

int stk[N],top;//我声称这个栈维护的是从根到叶子的链

void zako_problem()
{
	read(n);
	For(i,1,n) read(p[i]);
	top=0;
	stk[++top]=1;
	For(i,2,n){
		while(top>1&&(p[i]-p[stk[top]])*(stk[top]-stk[top-1])
		    >=(p[stk[top]]-p[stk[top-1]])*(i-stk[top]))
		    top--;//如果这个叶子不是最优了,就被共同支配了,可以扔了
		int j=stk[top];
		f[i]=f[j]+(i-j)*(p[i]+p[j]);
		stk[++top]=i;
	}
	printf("%lld\n",f[n]);
}

Q:老大,我们推了这么久,怎么代码和原本的正解完全一样啊?

A:是的,你说得对,这就是原本的代码啊。

Q:那老大,我们想了这么久是白干了吗?

A:你说得对,我们就是白干了!

永久支配引理

既然本题解名字都叫“到永久支配引理”了,那支配这里还是写详细一点吧。

不过说实话,写出来后,我才发现原来我之前其实会的根本不全。还是太菜了啊。

(声明:这里使用了 AI 辅助。辅助方式:这个引理就是和 AI 聊出来的,我让 AI 总结了一下当前对话,并给出一个草稿)

具体地:

约定与声明

决策树:表示由 $pre(i) \rightarrow i $ 形成的外向树。

栈的约定:按编号插入,\(c\) 入栈前维护的是链 \(s_1<\dots<s_k\),相邻两点满足“后一点由前一点转移”,即均有 $s_i\rightarrow s_{i+1},(1\le i\le k-1) $。本引理只处理栈顶相邻的 \(a<b,a=s_{k-1},b=s_k\) 与即将插入的 \(c\)。

引理 1

\[g_i=g_{pre(i)}+w(pre(i),i). \]

证明见上文。

引理 2

\[T_q(j)-T_q(a)=(q-a)(q-j)\bigl(K(a,q)-K(j,q)\bigr). \]

证明见上文。

引理 3(弦条件)

对 \(a<b<c\),令

\( \lambda =\frac{b-a}{c-a} \in (0,1)\)

记 \(d=p_b-\bigl((1-\lambda )p_a+\lambda p_c \bigr)\),即“ \(b\) 的点比弦 \(ac\) 在 \(b\) 处高出多少”。则以下两件事等价:

  1. \(d \le 0\),即 \(b\) 在弦 \(ac\) 上或下方;
  2. \(K(a,b) \le K(b,c)\);
  3. \(K(a,b) \le K(a,c) \le K(b,c)\)。

数形结合易证

证明:\(d \le 0\) 两边乘 \(c-a>0\):

\[(c-a)p_b \le (c-b)p_a+(b-a)p_c. \]

而 \(K(a,b) \le K(b,c)\) 即 \(\dfrac{p_b-p_a}{b-a} \le \dfrac{p_c-p_b}{c-b}\),两边乘 \((b-a)(c-b)>0\) 并整理,恰好是同一个不等式。第 3 条与第 2 条等价,因为 \(K(a,c)\) 是 \(K(a,b)\) 与 \(K(b,c)\) 的加权平均(\(b\) 在 \(a,c\) 之间)。

引理 4(永久支配引理)

设定:处理 \(c\) 时栈顶为 \(b\),次顶为 \(a\),\(a<b<c\)。则,以下三件事等价:

1. \(b\) 在弦 \(ac\) 下

\[K(a,b)\le K(b,c) \quad \Longleftrightarrow \quad d\le 0 . \]

也即弹栈条件。

2. \(b\) 的决策弱于 \(a\):

\[T_c(b)\le T_c(a)\le g_c \]

即决策点 \(b\) 弱于决策点 \(a\)(但不保证 \(a\) 为最优)。

3. 任意未来查询 \(b\) 均不为严格最优:对每个 \(q>c\),

\[T_q(b)\le(1-\lambda)\,T_q(a)+\lambda\,T_q(c)\le\max\{T_q(a),T_q(c)\}. \]

也就是说,\(b\) 永远不会严格优于 \(a,c\) 两者;删掉 \(b\) 不会改变任何后续答案。

详细证明

引理 2 证明了“\(b\) 在弦 \(ac\) 下”和“\(b\) 的决策弱于 \(a\)”等价。接下来以前者为基础。

\(b\) 由 \(a\) 转移,故

\[g_b=g_a+w(a,b). \tag{1} \]

\(c\) 计算 \(g_c\) 时 \(a\) 是合法候选(\(a<c\)),故

\[g_c\ge T_c(a)=g_a+w(a,c). \tag{2} \]

第 1 步:作差,消掉 \(p_q\)

由 \(\lambda\) 的定义,\(b=(1-\lambda)a+\lambda c\)。于是

\[\begin{aligned} &T_q(b)-\bigl((1-\lambda)T_q(a)+\lambda T_q(c)\bigr)\\ &=\Bigl[g_b-(1-\lambda)g_a-\lambda g_c\Bigr] +q\Bigl[p_b-(1-\lambda)p_a-\lambda p_c\Bigr] -p_q\Bigl[b-(1-\lambda)a-\lambda c\Bigr]\\ &=\Bigl[g_b-(1-\lambda)g_a-\lambda g_c\Bigr]+q\,d. \end{aligned} \]

最后一项因为 \(b\) 是 \(a,c\) 的凸组合而整项为 \(0\)。这一步是“对任意 \(q\) 一致”的关键:查询点 \(Q=(q,p_q)\) 只以 \(q\,d\) 的形式出现。

第 2 步:用 (1)(2) 估计方括号

\[\begin{aligned} &\quad g_b-(1-\lambda)g_a-\lambda g_c\\ &=(g_b-g_a)-\lambda(g_c-g_a)\\ &\le w(a,b)-\lambda\,w(a,c) \qquad\bigl(\text{用 }(1)(2),\ \lambda>0\bigr). \end{aligned} \]

用 \(b-\lambda c=(1-\lambda)a\) 化简:

\[\begin{aligned} &\quad w(a,b)-\lambda w(a,c)\\ &=p_a(b-\lambda c)-a p_b+\lambda a p_c\\ &=(1-\lambda)a\,p_a-a p_b+\lambda a\,p_c\\ &=-a\Bigl(p_b-(1-\lambda)p_a-\lambda p_c\Bigr)=-a\,d. \end{aligned} \]

第 3 步:合并证得任意未来查询

\[T_q(b)-\bigl((1-\lambda)T_q(a)+\lambda T_q(c)\bigr)\le -a\,d+q\,d=(q-a)d\le 0 . \]

这里用了 \(d \le 0\)(弹栈条件)和 \(q>c>a\),所以 \(q-a>0\)。右边是两个实数的凸组合,自然不超过二者最大值,于是

\[T_q(b)\le(1-\lambda)T_q(a)+\lambda T_q(c)\le\max\{T_q(a),T_q(c)\}. \]

算法实现的正确性归纳(一段废话)

设处理完 \(i\) 后栈为 \(S_i=(s_1<\dots<s_m=i)\),维护三条不变量:

  • (P1) 相邻转移:\(g_{s_{t+1}}=g_{s_t}+w(s_t,s_{t+1})\);
  • (P2) 边斜率严格递减:\(K(s_1,s_2)>\dots>K(s_{m-1},s_m)\);
  • (P3) 对任意 \(q>i\),\(\max_{j\le i}T_q(j)\) 在 \(S_i\) 上取到(不在栈上的点永远不是唯一最优)。

弹栈合法:\(b\) 被弹时,由引理 4,\(q>c\) 时 \(T_q(b)\le\max(T_q(a),T_q(c))\),而 \(a,c\) 都还在(或同样可继续替换),故 (P3) 不破。

替换链有限:被弹点由当时的 \(a,c\) 支配;若 \(a\) 或 \(c\) 后来也被弹,就用它们被弹时的支配对继续替换。弹出时间严格递增,链必终止于某个仍留在栈上的点,所以“永远”成立。

栈顶就是最优点:弹栈结束时,剩余链满足 \(K(s_{t-1},s_t)>K(s_t,i)\)(或只剩一个点)。归纳可得

\[K(s_1,i)>K(s_2,i)>\dots>K(s_m,i), \]

因为 \(K(s_{t-1},i)\) 是 \(K(s_{t-1},s_t)\) 与 \(K(s_t,i)\) 的加权平均,而 \(K(s_{t-1},s_t)>K(s_t,s_{t+1})>K(s_t,i)\)。由引理 2,\(T_i(s_1)<\dots<T_i(s_m)\),故栈顶最大;被弹掉的点又都不优于栈顶。于是

\[g_i=T_i(s_m)=g_{s_m}+w(s_m,i),\\ f_i=f_{s_m}+(i-s_m)(p_{s_m}+p_i). \]

启示

这个东西看着很复杂并非看着,但是实际上只有一个核心,就是:

对每个 \(q>c\),存在

\[T_q(b)\le\max\{T_q(a),T_q(c)\}. \]

这也就是 \(b\) 能被永久删除的原因,也就是永久支配。

所有斜率优化,单调栈单调队列等,能够做到均摊,就是因为每个点只会进出一次。而“只出一次”就是因为一个决策一旦被弹出,就会被候选决策们永久支配。

这给了我们一个新的决策观察方向:我们可以不只看两个决策之间的关系,而是多个决策对单个决策形成的共同支配。

(不过似乎没啥用就是了)

后话

update on 11/4 发布后,朋友提醒:woc坏了,斜率的关系写反了QAQ。对不起!!!

update on 11/5 既然本题解名字都叫“共同支配”了,那共同支配这里还是写详细一点吧。新增了“共同支配引理”这一块。顺便更新了一波 Latex 语法。

说实话,认认真真写(抄)完了这部分才发现,自己之前只懂了个皮毛。AI 大人强强!

posted @ 2026-11-04 18:34  FarrisL  阅读(4)  评论(0)    收藏  举报