省选模拟赛 1

link

期望 100+100+15,实际 100+90+0,被卡常+写错文件名。

A

可以发现一个简单的 dp,也就是设 \(f_{l,r}\) 为删光 \([l,r]\) 的答案,那么显然有:

\[f_{l,r}=\min(\max(f_{l+1,r-1},w_{l,r}),\min_k\max(f_{l,k},f_{r,k})) \]

现在是 \(O(n^3)\) 的,我们需要优化。

我们发现,这支持二分答案,那么考虑二分答案,这个 dp 变成可行性,便可以使用 bitset 进行优化,得到 \(O(\frac{n^3\log n}{w})\) 的算法,实现精细可以通过。

我们并不满足于此,想办法取掉二分答案,仍然考虑这个可行性 dp,从小到大加入可用 \(w(l,r)\),那么其用处就是从 \(f_{l+1,r-1}\) 更新 \(f_{l,r}\),那么问题变为当 \(f_{l,r}\) 合法后,能够将哪些不合法的区间变为合法。

\((l,r)\to (l-1,r+1),(l,k),(k,r)\)

我们现在只需要快速查找到被更新的这些区间就行了,设查找的复杂度是单次 \(O(t)\),总复杂度就是 \(O(n^2t)\)

令人高兴的是,我们可以使用 bitset 去处理这个操作和拿出相应的 \(1\) 的位置,手写 bitset 支持提取 \(1\) 的位置集合即可。

事实上可以使用 STL _Find_First_ 函数,唐了。

B

首先可以发现明显的比较决策,当确定了选出哪些 \((a_i,b_i)\) 之后,一定按照 \(b\) 从大到小放。

那么我们先把所有元素按照 \(b\) 从大到小排序,设 \(f_{i,j}\) 为前 \(i\) 个点对里选出 \(j\) 个的最小代价,有:

\[f_{i,j}=\min(f_{i-1,j},f_{i-1,j-1}+b_i(j-1)+a_i) \]

现在可以 \(O(n^2)\) 了,考虑优化。

发现函数下凸,证明显然。

这启发我们想到 Slope Trick,分析其斜率数组(原数组差分数组)可得:

\(f_{i-1}\) 的差分数组是 \([c_1,c_2\dots ]\),则 \(f_{i-1,j-1}+b_i(j-1)+a_i\) 的差分数组为 \([a_i,c_1+b_i-a_i,c_2,c_3\dots]\)

考虑这两个函数所表示的凸壳,可以发现除开原点,这两个凸壳有且只有一个交点,这就说明了前一半取第一种决策,后一半取第二种决策。

事实上可以考虑打表,设 \(b_i=[f_{i-1,j}<f_{i-1,j-1}+b_i(j-1)+a_i]\),可以发现其为一串 \(1\) 接上一串 \(0\),再写一个对拍拍个七八千组。

因此我们可以二分这个转折点,并维护转移。

注意到设转折点是 \(x\),则 \(f_i\) 的差分数组变为:

\([c_1,c_2\dots c_{x-1},b_i(x-1)+a_i,c_x+b_i,c_{x+1}+b_i\dots]\)

可以使用平衡树维护区间加单点插入做到 \(O(n\log ^2n)\)

这是考场思路,并且平衡树外层二分容易优化到平衡树上二分。

事实上转折点的实际意义是两个递增斜率序列的相对关系第一次变化的位置,容易平衡树上二分。


C

强如怪物,单独开篇。

link

posted @ 2024-12-27 18:53  spdarkle  阅读(50)  评论(0)    收藏  举报