青年节 OI 大学习
二进制
操作次数其实就是逆序对数量。
最小化操作次数时,\(0\) 和 \(1\) 内部的相对顺序显然不变,所以逆序对一定在 \(0\) 和 \(1\) 之间产生。
考虑 \(\text{DP}\),由于要先保证匹配次数,再保证逆序对数量最小,这两者相互独立,所以可以设两个状态来 \(\text{DP}\)。
要实现这两个代价的计算,手玩一下,可以通过记录当前串在 \(\text{KMP}\) 自动机上的状态编号,以及当前串 \(0\) 的个数来转移。
所以设 \(f_{i,j,k}=\) pair<int,int> 表示放了 \(i\) 个字符,其中有 \(j\) 个 \(0\),在 \(\text{KMP}\) 自动机上的状态为 \(k\),此时最大匹配次数和对应的最小交换次数。
直接写就是 \(O(n^3)\)。
简单模拟
\(\text{Part I}\)
考虑先对 \(x=l\) 跑一遍流程,可以得到一个 \(01\) 序列表示每个二元组有没有选。
当 \(x\) 增加 \(1\) 的时候,\(01\) 序列会有一段前缀保持不变,然后某一个 \(0\) 变为 \(1\),这一位后面全部变为 \(0\)。
这个过程足够简单,求出初始 \(01\) 序列后 可以用线段树进行维护,总复杂度 \(O(n \log_2 n)\)。
赛时以为 \(0\) 变 \(1\) 之后在后面还会有一些乱七八糟的 \(1\),不知道怎么想的。
\(\text{Part II}\)
考虑把所有 \([l,r]\) 一起做,当 \(a_i \leq l\) 的时候,直接全部减去 \(a_i\) 即可,当 \(a_i \in [l,r]\) 的时候,区间会被分为两部分,\([l,a_i-1]\) 和 \([a_i,r]\),其中 \([a_i,r]\) 在进行操作后会变成 \([0,r-a_i]\)。
由于 \(r-l+1 \leq 10^6\),所以这样的分裂操作最多会进行 \(10^6\) 次,且在整个过程中最多存在一个区间的左端点不是 \(0\)。
当分裂至所有区间长度均为 \(1\) 的时候,最多一个区间是非 \(0\)。
直接暴力模拟即可,需要一个堆进行维护,时间复杂度 \(O(n\log_2n)\)。

浙公网安备 33010602011771号