CF VP 记录

CF2048

D

记得 \(\sum\limits_{i=1}^n{n\over i}= n\log n\),不要记错了。唐题一个,发现贪心最优于是排序后暴力即可。

E

简单二分图构造题。考虑台阶形即可。

F

考虑如果操作一个 \(b_i\),那么我们会尽量让区间长。于是考虑一个 \(b_i\) 会支配一个区间,这个可以笛卡尔树求。求完后我们就可以在树上 dp 了,设 \(f_{i,j}\) 表示当前在点 \(i\) 最大的数是 \(j\) 所操作最少次数。这个不好做考虑换维 dp,设 \(f_{i,j}\) 表示在点 \(i\) 操作了 \(j\) 使得最大值最小是多少。转移就是合并一下背包然后更新即可。注意到第二维很小于是直接做就没了。复杂度 \(\mathcal O(n\log^2V)\)

G

正难则反,考虑用总方案 \(V^{nm}\) 减去不合法的方案。考虑枚举不等式两边的取值就有:

\[\text{ans}=V^{nm}-\sum_x\sum_{y<x}f(x,y) \]

其中 \(f(x,y)\) 表示左右两边的值,考虑修改一下定义,设 \(f(x,y)\) 表示左边 \(\ge x\) 且右边 \(\le y\) 的答案,然后答案变成了:

\[\text{ans}=V^{nm}-\sum_if(i+1,i)-f(i,i-1) \]

现在考虑单次 \(f(x,y)\) 如何计算。考虑最普通的容斥,思路是我们考虑先求出钦定的答案然后容斥出恰好的答案。比如我们钦定有 \(i\) 行最大值小于 \(x\),考虑计算方案。我们继续容斥,用总方案数减去不合法数。注意到每列是独立的于是我们考虑每一列的情况。答案是 \((x-1)^iV^{n-i}-(x-y-1)^i(V-y)^{n-i}\)。于是我们就能得到 \(f\) 的式子了:

\[f(x,y)=\sum_{i=0}(-1)^i{n\choose i}\left((x-1)^iV^{n-i}-(x-y-1)^i(V-y)^{n-i}\right)^m \]

于是答案就可以 \(\mathcal O(nV(\log n+\log m))\) 计算。

H

考虑最后得到的串每个位置的来源。我们设第 \(i\) 个位置的来源是 \([l_i,r_i]\),初始有 \(\forall i\in[1,n],l_i=r_i=i\)。现在我们考虑一次操作 \(p\) 的影响,假设操作前每个位置的来源分别是 \([l_1,r_1],[l_2,r_2]\dots,[l_m,r_m]\) 那么我们对 \(\forall i[1,p)\) 进行扩展并把第 \(p\) 个位置删掉侯就会得到 \([l_1,r_2],[l_2,r_3],\dots[l_{p-1},r_p],[l_{p+1},r_{p+1}],\dots,[l_m,r_m]\)。注意到我们一次操作只会删掉 \(r_1\) 以及一个 \(l_p\),于是最终的形态一定是若干 \([l,r]\) 的区间满足,对于 \(l\)\(l_i\) 构成一个子序列,对于 \(r\)\(r_i\) 是一段后缀 \([k,n]\)。于是我们可以尝试对每个串的 \([l,r]\) 序列进行 dp。设 \(f_{i,j}\) 表示串的第一个 \([l,r]\)\([j,i]\) 的答案。注意为了保证计数的时候不会重复计算于是我们仅在最大的合法的 \(j\) 处统计答案。

具体的,转移考虑枚举右端点 \(i\),考虑不同情况下应该如何转移。我们考虑原将来的串看成一些 0 和 1 的连续段,我们在这上面走就是在进行 dp 的转移。如果当前在 1 上面我们就可以正常走,于是可以从 \(f_{i,j}\rightarrow f_{i-1,j-1}\),如果在 0 上面,我们也可以有相同的操作,这里不重复写,考虑我们还可以跳过一些 0,转移到左边最近的 1 的位置,就有 \(f_{i,j}\rightarrow f_{i-1,las_j}\)。我们发现这个 dp 本质是区间平移,单点修改,于是我们令 \(j'=i-j\),然后每次从 \(f_i\)\(f_{i-1}\) 就有很多状态可以继承。考虑变化的是 \(las_i\) 的东西,于是我们就单独用一个变量记录即可。注意到 \(las_i\) 有单调性于是时间复杂度可以做到 \(\mathcal O(n)\)

I1

考虑从简单情况入手。我们发现如果最左边是 L 或者最右边是 R 那么这个位置的 a 一定是 0,可以递归到一个子问题。于是考虑每次处理序列的左右两端,分讨不同情况。具体如下:

  • \(s_1=L,s_n=R\),刚刚说了就是直接扔掉两边的,然后剩下的部分整体带了一个 +1 的标记。
  • \(s_1=s_n=L/R\),以 \(s_1=s_n=L\) 为例,另一种情况同理。考虑 \(a_1=0\) 是显然的,假设 \(a_n=x\),考虑 \(a_i,i\in[2,n-1]\) 的取值范围是 \([1,x)\) 且每种值都存在,证明可以考虑反证法。假设存在大于 \(x\)\(a_i\),那么考虑 \(a_i\) 如果要合法那么一定就会和 \(a_n\) 的限制冲突,具体不详细说明。这种情况的处理方式同上即可。
  • \(s_1=R,s_n=L\),此时我们发现序列中所有数一定大于 0,这是显然的。然后考虑所有数都填 1 就能构造出合法的方案了。注意到我们每次递归第二种情况的时候要求了从 0 到一个上界的数都存在,但是这种条件下 0 不存在,于是就不合法了。所以我们只需要判掉第二种情况里面套第三种情况的序列就可以直接递归构造了。

CF2066

A

脑筋急转弯好题!考虑是否全排列,两种情况分开处理。对于全排列的情况,我们可以去询问 1 和 \(n\) 然后看正反是否相同且路径长度大于等于 \(n-1\) 即可;否则我们就考虑不在序列中的一个数,这个数代表的点在 A 类图中一定没有出边,于是询问这个点和任意一个出现过的点即可。

B

首先考虑有多个 0 的情况一定是保留最前面的 0 最优,然后考虑只有一个 0 的时候,我们从 0 的位置开始往前扫,如果不合法那么说明我一定会进行一次修改。考虑如果不改 0 可能之后还有修改就不优了,如果修改了 0 那么后面一定全部合法,于是选择后者即可。

C

考虑一个朴素的 dp,设 \(f_{i,j}\) 表示操作完第 \(i\) 个数后,两个数相同,另外一个相对异或值为 \(j\) 的方案数。转移状态数是 \(\mathcal O(1)\) 的但是最后的状态可能很多,于是滚动数组然后用 map 存第二维即可。

D

对于计数题考虑找充要条件。考虑一个数字能填需要满足其前面还没有 \(c\) 个数大于它,注意这个限制是后缀的,所以我们考虑值域的前缀。对于 1 我们只能放在 \([1,c]\),以此类推,我们能够得到 \(i\) 能够放置的区间 \([1,c+\sum\limits_{j<i}\text{cnt}_j]\),其中 \(\text{cnt}_j\)\(j\) 的数量。于是我们可以对其考虑 dp,设 \(f_{i,j}\) 表示考虑到 \(i\) 填了 \(j\) 个数的方案数。转移考虑枚举 \(i\) 放了多少个,设为 \(k\),其上界是 \(\min(j,c)\)。此时我们能够知道 \(i\) 填数范围是 \([1,c+j-k]\),首先我们需要判断这个上界是否合法,因为可能存在已经给出的 \(i\) 的最右边不在区间内的情况。判断转移合法性之后就简单了,现在只需考虑填数的方案数即可。因为之前已经有 \(j-k\) 个数,于是还剩下 \(c\) 个空位,但是考虑到原来的序列本身还有一些数已经确定,于是还要减去这段前缀区间内 \(\ge i\) 的数的个数,设为 \(s\)。考虑我们需要将 \(k\)\(i\) 放进去,但是可能原来序列中也有一些 \(i\) 了,其数量设为 \(t\),那么我们的方案数就是 \(c-s\choose k-t\)。于是最后的 dp 式子就是:

\[f_{i,j}=\sum_{k\le\min(c,j)}f_{i-1,j-k}\times{c-s\choose k-t} \]

时间复杂度 \(\mathcal O(nmc)\)

E

考虑如果有两个相同重量的桶那么我们就能比较他们,并且比较了之后这两个桶里面的水我们就能自由调动了。假设我们现在有 \(x\) 的水能够自由调动,考虑如何拓展。思考不难发现有两种情况:

  1. \(x\ge a_i\),我们能够分出恰好 \(a_i\) 的水去比较,于是 \(a_i\) 也能用了。
  2. \(a_i<a_j,a_i+x\ge a_j\),于是我们考虑给少的分一些水然后就可以比较两个桶了,然后这两个桶的水就都能用了。

于是我们给 \(a_i\) 排序,从小到大考虑水,每次先找到两个相同的然后开始拓展。容易得到单次 \(\mathcal O(n)\) 的做法。现在考虑优化。

可以发现每次拓展了一个新的桶之后我们又可以多拓展很多桶,并且考虑上述两种拓展的方法其 \(x\) 的增长都是 \(\ge 2a_i\) 的。于是我们考虑倍增值域,更进一步,我们能够联想到一个东西,叫做倍增值域分块。现在考虑分块后如何拓展。

对于一个 \(2^k\le a_i<2^{k+1}\) 的桶,如果我们能够拓展出它,那么我们一定能够拓展整个块内的元素,证明上面已经提过就不赘述了。于是每次我们从小到大去扫这 \(\mathcal O(\log)\) 个块,分别去看两种方式是否存在一种能够拓展这个块内的一个元素即可。

具体的,我们考虑对于每个块维护两个 multiset 分别记录 \(a_i\)\(\Delta=a_{i+1}-a_i\),然后每次拿块内最小的去和 \(x\) 进行比较即可。注意块间的 \(\Delta\) 不要算漏即可。时间复杂度 \(\mathcal O(n\log V)\)

CF2115

B

首先倒着考虑每个操作,因为确定一个数不好做于是转化成确定一个数大于等于多少,然后判合法即可。

C

思考两种不同的操作在什么时候要做什么时候不做。对于闪耀,如果全局最小值大于 1 那么一定要做;对于普通,如果当前所有数都相同,我们做了之后可能没有我们等闪耀然后一直全局减更优,这里需要比较一下代价;否则就可以直接做普通的操作。

注意到我们考虑是否做操作取决于全局最小值,于是我们考虑 dp,然后记录最小值,于是有 \(f_{i,j}\) 表示还有 \(i\) 次操作,全局最小值为 j 的概率。转移比较困难考虑加入更多的限制。这里有个 trick,具体可以看这道题的题解。就是说我们记录了最小值后就只用考虑上面的东西。于是就可以正常写转移了:

\[f_{i,j,s=}\begin{cases} 1 & i\ge0\wedge j=1\wedge s=0\\ p\times f_{i-1,j-1,0}+(1-p)\times \max(f_{i-1,j-1,n-1},f_{i-1,j,0}) & i>0\wedge j>1\wedge s=0\\ p\times f_{i-1,j-1,s}+(1-p)\times f_{i-1,j,s-1} & i>0\wedge s>0\\ 0 & \text{Otherwise} \end{cases} \]

此时 dp 时间复杂度为 \(\mathcal O(nmV^2)\),会寄,考虑一个优化。就是说当我们的 \(s\) 第一次变成 0 的时候 \(s\) 的上界就是 \(n-1\) 了,所以我们去枚举 \(s\) 什么时候变成 0 第三维就只用考虑到 \(n\) 了。式子也比较简单:

\[ans=\sum_{s\ge i}(1-p)^s\times p^{i-s}\times{i-1\choose s-1}\times f_{m-i,\max(mi-i+s,1),0} \]

其中 \(mi\) 是全局最小值。但是你如果这么写会炸精度,所以我们需要递推前面的系数。递推考虑 \(g_{i,s}\) 表示前面那坨,于是我们拆组合数就可以 \(\mathcal O(1)\) 转移了。

D

二选一异或有点复杂,所以我们假设先选择 \(a\),然后再进行调整。于是每次调整都需要异或上 \(c_i=a_i \oplus b_i\),所以我们只关注是否调整。对于博弈双方我们肯定都会按位从高到低考虑,否则一定不优。若考虑到第 \(i\) 位,那么决定最后状态的一定是最后一个第 \(i\) 位为 1 的,假设为 \(x\),我们可以进行选与不选的决策来调整。每次简单判断一下即可。注意更新答案后要将 \(c_j\) 中最高位是 \(i\) 的给异或上 \(x\),这个表示如果这一位选进答案,那么 \(x\) 是否选择的状态就要改变。每次做完最高位会减一,所以没有后效性可以大胆写。

E

对于容量小的我们可以直接做普通的完全背包,如果容量很大我们就可以用一个 trick,具体见 P9140。简单来说就是我们可以在一定范围进行贪心,然后在最后调整。注意到贪心选择的物品可能不对所有点做贡献,因为我们是在 DAG 上做背包。所以我们可以钦定用哪个作为贪心点然后去拓展即可。

CF2129

B

因为是排列所以我们可以从小到大考虑每个数。对于一个数,如果不变那么贡献是前面比它大的数个数,如果改变那么贡献是后面比它大的数的个数,取最小值即可。

C

首先我们得找到一个确定的括号,这样我们才可以判断。因为题目保证至少有一个 ( 和一个 ) 所以字符串中至少有一个 () 或者一个 )(,考虑前者贡献为一,后者无贡献于是考虑二分找即可。这里需要用掉 \(1+\left\lceil\log_2n\right\rceil=11\) 次查询。

C1

考虑还有 500 多次查询所以我们每次确定 2 个位置即可。我们考虑一个形如下面的查询:

( ( i j ( j i

我们分讨一下 4 种取值对应的结果即可。

C2

我们尝试让每次询问确定更多的位置,考虑一组形如 (((iii 的查询,其取值要么是零要么是长度的一半,我们状压一下就可以每次查询 8 个位置,因为有 \(7+\sum_{i=0}^82^i=518\) 如果再大就超过限制了。这样一共需要查 \(11+\left\lceil n\over 8\right\rceil=136\) 次。

C3

上面我们考虑括号嵌套的查询,其实我们还可以让括号并排,这样能构造出形如下面的东西:

( i ( i ( i ( ( j ( j ( j ( ( k ( k ( k

每次一个位置所带来的贡献要么为零要么为 \(cnt\times(cnt+1) \over 2\),考虑构造出不同的 cnt 保证每种组合唯一。可以构造出如下的 cnt 序列:

1,2,3,5,7,10,15,21,30,43,61,87,123

最后我们一次查询能够确定 13 个位置,总询问次数为 :\(11+\left\lceil n\over 13\right\rceil=88\)

D

神秘计数题我们考虑先去寻找性质,然后通过性质入手。

我们先去考虑一个位置 \(i\) 被贡献的情况,不考虑其他位置,于是左右对称,我们考虑左边。首先染色的位置应该从远到近,否则就贡献不到当前考虑的位置。然后考虑我们贡献的上限能是多少。最近的位置肯定是 \(i-1\),下一个不能是 \(i-2\),因为这时我们 \(i-1\) 的贡献就会给 \(i-2\),于是下一个位置实际是 \(i-3\)。再下一个呢?经过实践我们发现是 \(i-7\)。发现了吗?每次能作贡献的最右端点形如 \(i-2^k+1\),所以每个位置的贡献上界是 \(\log\) 的。

然后我们考虑一个位置被填了后,左边的位置显然不能贡献到右边去了,所以一个问题就被简化成了子区间,于是我们肯定是往区间 dp 的方向思考。所以首先我们的状态有 \(f_{i,j}\) 表示区间 \([i,j]\) 的答案,但是显然这样没法进一步转移,所以我们需要增加限制。因为我们转移的时候肯定要去枚举那个划分的位置,考虑那个位置对外置位做的贡献以及那个位置得到贡献的情况。考虑新划分出来的两个子区间肯定对划分位置有贡献,于是我们重新定义 dp 状态。设 \(f_{i,j,x,y}\) 表示考虑到了区间 \([i,j]\) 并且区间内没有染色,但是 \(i-1\)\(j+1\) 已经被染色,区间对 \(i-1\) 的贡献为 \(x\),对 \(j+1\) 的贡献为 \(y\)

转移的时候我们枚举了划分位置 \(k\),考虑 \(k\) 对外置位的贡献。如果 \(k\) 在区间左半部分,那么会对 \(i-1\) 有 1 的贡献;否则对 \(j+1\) 有 1 的贡献。枚举的时候注意减掉。然后两个子区间对 \(k\) 的贡献就枚举一下即可。注意因为是统计排列数,考虑两个子区间独立,于是在排列中只要相对顺序正确即可,所以还要带一个组合数 \(j-i\choose k-i\)。最后转移就是 \(f_{i,j,x,y}\leftarrow f_{i,k-1,x't}\times f_{k+1,j,q,y'\times{j-i\choose k-i}}\)。时间复杂度 \(\mathcal O(n^3\log^3n)\)

E

发现单次的修改是简单的,但是跟边数有关。注意到 \(n,m\) 同阶于是考虑对 \(m\) 分块跑莫队。然后注意到正常用平衡树是 \(\mathcal O(q\sqrt m\log n)\) 的修改加上 \(\mathcal O(q\log n)\) 的查询,于是考虑值域分块平衡复杂度。注意如果直接按照度数分块可能出现很多点度数为零导致块长爆炸,于是我们按照度数加点数分块,于是就是 \(\mathcal O(q\sqrt{n+m})\) 的。

CF2164

A

显然要最值区间包含目标数。

B

考虑如果有多于一个偶数那么一定可以,如果有一个偶数我们可以扫一遍。现在我们要处理的就只有全为奇数的情况。考虑两个奇数要不合法必须是奇数=偶数×奇数+奇数的情况,然后因为偶数至少为 2 所以固定一个数后,若想构造出不合法的数列最大值每次会扩大一倍,于是最长的不合法序列是 \(\log V\) 的,我们就暴力跑多余 \(\log V\) 个数即可。

C

注意到有的怪杀了剑会消失,有的怪杀了剑会变得不劣。于是我们给怪分成两类,先打可以继续用剑的一类,打到不能打的时候再考虑剩下的。注意到每次打怪剑一定变得不劣,所以我们考虑从小到大打。打完直接双指针看剩下的东西即可。

D

简单题,直接倒着扫一遍即可。

E

注意到答案至少为 \(\sum e\),现在考虑多出来的答案会在哪里?就是说我们走不了路之后就会进行一次操作二。我们考虑给这个图补成一张欧拉图,这样我们就能走回路了,相当于我们需要给奇度数点做匹配,满足添加的边最少。注意到题目的限制是最大编号的边的权值,所以我们考虑重构树,加入一条边就相当于连通了两个连通块,于是当前时刻这里面的匹配点的权值都是这条边。考察最后建出来的树,对于两个匹配点的最小权值应该是其 lca 到根链上的最小值。于是我们考虑 dfs 一遍记录最小值即可。

F

发现原来的限制让人很不舒服,于是我们对 \(p_x<p_y\) 的限制取逆,变成 \(x\) 出现在 \(y\) 前面。这样的话如果我们对一个子树加入一个根的父亲,相当于就是在子树构成的子序列中插入了一个 \(a_i\) 并且让一段后缀 \(a\) 全部减 1。因为每次都是后缀减所以我们的子序列在任意时刻一定递增,并且我们插入根的父亲的位置一定是确定的,否则就不能满足子序列递增的条件。当我们合并两棵子树的时候本质上是在做序列的归并。注意到相同数值的位置不重要于是归并所带来的贡献就是每一个 \(a\) 的颜色段带了一个组合系数。dfs 暴力维护颜色段是 \(\mathcal O(n^2)\) 的,考虑用平衡树即可。平衡树需要完成的操作本质上就是后缀减 1,区间有交合并。

G

思考怎么构造能够得到一些有用的信息?可以发现如果把任意一个排列正反询问能够得到每个点的度数。然后显然还有对于任意一个询问我们差分答案序列后能够得到单点对于一段前缀的答案。现在我们聚焦于一个点,考虑怎么快速求出其答案?注意到我们一次询问能够得到一个点关于区间的信息,考虑如何通过不同的排列快速得到能够差分的区间信息?可以想到二进制分组。分完后我们能够得到每个点对于二进制下每一位为 0/1 的所有点的关系。这时我们可以先从度数为 1 的点入手进行拓扑,这样我们查询一个点的区间就只能查到一个点的信息,然后就能够还原出原来的结果。删掉用过的点后要减掉它对于没被用的点的贡献。这样我们的询问次数就是 \(\lceil2\log_2 n\rceil+1=33\),然后考虑优化,我们将二进制变成三进制,现在次数就是 \(\lceil3\log_3n\rceil+1=31\) 于是就做完了。

CF2165

A

贪心板子。

B

考虑一个元素 \(x\) 是否会出现在最后的集合中。如果它没有出现,那么我们需要将它“藏”起来,也就是说我们分出的每个包含 \(x\) 的集合需要满足条件:\(x\) 的数量小于等于这个集合的众数个数。然后我们考虑如果要选择这个元素,不管我们选了多少个,我们都能提供 \(cnt\) 个”藏身之处“,所以所有选择的元素的个数和要大于等于没有选择的元素个数中的最大值。这个限制就可以直接背包做了。

C

考虑贪心,从最高位开始往低位考虑。如果这个位置需要填 1 但是 \(a_i\) 中都没有 1 那么我们需要把一个 \(a_i\) 的这一位变成 1,为了让变化最小于是我们选择最大的 \(a_i\)。如果这一位刚好有一个满足条件的 \(a_i\) 那么我们直接用了就好了,这样我们让这个 \(a_i\) 减掉这一位的 1 继续往后做即可(因为后面比较大小的时候前面的 1 会影响后面的判断)。如果有多个 1 那么我们可以让一个 \(b_i\) 的这一位取到 1 的同时让另外一个 \(b_i\) 的这一位取 0 但是后面全部取 1。于是贪心做即可。但是这里找最大的 \(a_i\) 单次是 \(\mathcal O(n)\) 的不能接受,考虑有用的 \(a_i\) 实际只有 \(\log V\) 个,因为修改操作只会出现至多 \(\log V\) 次,于是仅保留最大的 \(\log V\)\(a_i\) 即可。时间复杂度 \(\mathcal O(n\log n+q\log^2V)\)

D

经过观察发现这本质是一个匹配问题,并且我们可以贪心地去解决。我们可以考虑按值域从小到大贪心,这样就一定不会出现交错导致匹配数丢失的情况。具体实现可以对每个数值记录下位置,然后分别开左右两个 set 去维护匹配,注意代表左边的 set 去匹配代表右边的 set 即可。

E

我们考虑对问题进行反演,考虑去求单条路径颜色最多为 \(i\) 的情况下颜色最多是多少。这样我们求答案的时候就是取后缀 \(\min\) 即可。现在考虑去挖掘题目性质,考虑同一种颜色一定构成一个连通块。证明是简单的:

如果存在多个连通块,我们考虑仅保留一个连通块,将其他连通块用其周围的颜色代替,这样操作后在满足题目限制的情况下一定不劣,于是我们每次要求每种颜色仅构成一个连通块即可。

现在我们开始考虑这个问题。我们可以先进行缩点在新的树上考虑其直径 \(d\),如果将直径的中点作为根,那么新树的深度为 \(\lfloor {d+1\over 2} \rfloor\),颜色数为树的结点数。但是需要特别注意如果直径为偶数的情况中间其实是没有点的,怎么办呢?我们可以先当成奇数处理,把问题化归为 \(d=2\) 的时候进行处理,对于最后一小部分单独考虑。这里有一个脑筋急转弯,对于答案为 2 的情况最多的颜色数应该是节点最大度数。想到这个就可以做了,我们先处理出每个点的度数以及度数的个数,然后考虑依次干掉叶子节点,也就是合并连通块(可看成缩点),每次维护一下度数,并更新答案即可,精细实现可做到线性。

F

以下的数字均代表特殊序列的位置的编号。

首先是经典 trick:我们转成求对于左端点为 \(i\) 时右端点合法的最小点 \(rp_i\)。考虑 \(rp_i\) 的转移要么是 \(i\) 作为特殊序列的开头,要么是取后缀 \(\min\)。我们考虑处理出每个位置作为特殊序列开头的最小右端点。首先观察限制:21435。注意到固定了 2 之后 1 一定是右边第一个比 \(a_i\) 小的数,此时我们就需要找一个 435 与其匹配。假设我们已经处理好了 435,那么我们匹配的条件就是 \(pos_1<pos_4,a_i<a_{pos_3}\),这是一个二维数点,可以离线扫描线解决,于是问题变成了如何处理 435。

考虑枚举 3,现在 4 和 5 的组合存在很多个,直接做肯定不行,考虑寻找性质或者看能否支配。然后本题最妙也是本题的难点就来了,考虑对于一个 3 找到其右边第一个比它大的数作为 5 即可。考虑证明:

假设找到的不是右边第一个比它大的数,那么 3 和它之间还存在至少一个位置满足条件,考虑调整到右边第一个大于 3 的数。如果这个数大于 4 那么调整一定更优;否则我们考虑将 3 调整到这个位置一定更优。于是得证。

所以我们找右边第一个大于这个位置的数作为 5 即可,找 4 就是左边第一个在 3 和 5 之间的数即可。找 1 和 5 考虑单调栈,找 4 考虑可以按值域从大到小插入,线段树二分即可。

posted @ 2025-10-02 21:18  Lyrella  阅读(29)  评论(0)    收藏  举报