[AGC007B] Construct Sequences

发布时间 2023-09-28 16:45:12作者: Schucking_Sattin

[AGC007B] Construct Sequences

[AGC007B] Construct Sequences

先满足 \(a\) 单增,\(b\) 单减,构造一个 \(a = \{ N, 2N, \dots, nN \}\)\(b = \{ nN, \dots, 2N, 1N \}\),然后大家都在同一起跑线上。这里 \(N = 2\times 10^4 + 5\),是为了保证答案 \(a, b\) 元素大小关系的正确。这个 扩倍 卡了我很久!

首先要使 \(a_{p_1} + b_{p_1}\) 是唯一最小值,那就钦定 \(a_{p_1} + b_{p_1}\) 就等于 \(n + 1\),然后将其它 \(a_{p_i} + b_{p_i}\) 抬高。将 \(a\)\(p_1\) 右侧的元素集体加一,\(b\)\(p_1\) 左侧的元素集体加一,此时划归到大小为 \(n - 1\) 的子问题。

注意记录答案是在过程中进行的,才能保证 \(a + b\) 单增——所以你应该理解了,为什么在最初要进行扩倍。如果不扩倍,虽然 \(a, b\) 确实一直都是满足单调性的,但答案数组可不一定。幸运的是,\(a, b\) 中元素的偏移量最多为 \(n\),因此我给每个元素扩倍,实际上是让一个元素对应了一段 足够大的值域,让它在这个值域上进行变化,而值域是始终保持单调条件的。

这样做是 \(O(n^2)\) 的,可以用数据结构维护做到 \(O(n\log{n})\)

但是听说还可以更给力一点,做到线性。

upd:我是憨憨!以下分别给出 \(\color{black}{\text{b}}\color{red}{\text{ottyl}}\)\(\color{black}{\text{l}}\color{red}{\text{iuhangxin}}\) 的线性构造方式。

  • \(\color{black}{\text{b}}\color{red}{\text{ottyl}}\) 的构造:同样是扩倍,直接给 \(a_{p_i}\) 加上 \(i\) 不就可以了吗!!!

  • \(\color{black}{\text{l}}\color{red}{\text{iuhangxin}}\) 的构造:很不一样,但是一个有趣的调整法。

    初始 \(a = \{ 1, 2, \dots, n \}\)\(b = \{ m - 1, m - 2, \dots, m - n \}\),其中 \(m = 10^9 - n\),考虑对 \(a\) 中的元素进行加操作,对 \(b\) 中的元素进行减操作。

    然后将 \(a_{p_i}\) 加上 \(i\),这样 \(b, a + b\) 都满足了,但 \(a\) 不单增。

    \(a_{x - 1} > a_x\)\(a_x\) 加上 \(w = a_{x - 1} - a_x + 1\),同时给 \(b_x\) 减去 \(w\)。这时 \(b\) 又不单减了!

    也就是说,在调整过程中,要同时考虑 \(a, b\) 的合法性。我们要给 \(a_x\) 加上一个数 \(w\)\(b_x\) 减去一个数 \(w\),最优策略下,取 \(w = \max(a_{x - 1} - a_{x} + 1, b_{x} - b_{x - 1} + 1, 0)\)

    这样 \(a + b\) 是不变的,且 \(a, b\) 时刻保证从开头到当前位置是合法的。当 \(a_n, b_n\) 确定下之后,整个序列都是合法的了。

    确实是 \(\color{black}{\text{l}}\color{red}{\text{iuhangxin}}\) 能想出来的做法%%%

代码就没必要放了。