题意:
有一个长度为 $ n $ 的序列 $ a $ ,其中所有元素都为 $ 1 $ 或 $ 2 $ ,要求进行 $ q $ 次操作,每次操作为以下之一:
-
$ A $ $ s $ :询问是否存在 $ a $ 的连续子序列满足其中元素总和为 $ s $ ,若有合法的方案,输出这个方案的左右端点位置(多种方案时输出左端点最小的方案),否则输出 $ none $ 。
-
$ C $ $ i $ $ val $ :将 $ a_i $ 改为 $ val $ $ ( $ $ val $ ∈ \(\{\) \(1\) ,\(2\) \(\}\) \()\) 。
思路:
- 先考虑不带修的情况:
我们将左端点设为 $ l = 1 $ ,二分查找前缀和第一次大于等于 $ s $ 的位置 $ pos $ 设为 $ r = pos $ 。
当 $ sum(l,r) = s $ 时,区间 $ [l,r] $ 即为最终答案。
当 $ sum(l,r) > s $ 时,由于 $ a_i $ ∈ \(\{\) \(1,2\) \(\}\) ,那么一定满足 $ a_r = 2 $ 且 $ sum(l,r) = s + 1 $ 。当 $ a_1 = 1 $ 时, $ sum(l + 1,r) = s $ ,那么区间 $ [l + 1,r] $ 即为最终答案;当 $ a_1 = 2 $ 时,右移左端点 $ l $ ,$ l = l + 1 $, $ sum(l,r) = s - 1 $ ,右移右端点 $ r $ , $ r = r + 1 $ ,如果 $ a_r = 1 $ ,那么区间 $ [l,r] $ 即为最终答案;如果 $ a_r = 2 $ ,重复以上过程,直至 $ a_l = 1 $ 或 $ a_r = 1 $ ,那么区间 $ [l + 1,r] $ 或区间 $ [l,r] $ 即为最终答案;否则无解。
考虑以上过程,实际上是查询左端点 $ l $ 右侧最靠左的 $ 1 $ 的位置 $ pos1 $ 以及右端点 $ r $ 右侧最靠左的 $ 1 $ 的位置 $ pos2 $ ,由于 $ a_i $ ∈ \(\{\) \(1,2\) \(\}\) ,可以通过线段树维护区间最小值的位置来获得 $ pos1 $ 和 $ pos2 $ ,然后判断是否满足 $ a_pos1 = 1 $ 以及 $ a_pos2 = 1 $ ,进而可能产生两个可行区间 $ [pos1 + 1,r + pos1 - l] $ 以及 $ [l + pos2 - r,pos2] $ ,其中左端点较小的即为最终答案。
- 再考虑带修的情况:
通过线段树维护区间最小值的位置即可。
标签:val,蝴蝶,题解,sum,端点,区间,pos2,P6859,pos1 From: https://www.cnblogs.com/ShawyYum/p/17869945.html