P3514 [POI2011] LIZ-Lollipop
简要题意
给定一个只有 $1$ 和 $2$ 的序列,给出 $m$ 次询问,每次询问给出一个数 $k$,查询序列中有没有一个子串和为 $k$,如果有则输出区间两端点,如果没有输出 NIE。
策略分析
本题最重要的条件就是该序列中只含有 $1$ 和 $2$,因为这个条件,我们就可以得到下面这个性质:若 $k$ 可以被表示,则 $k-2$ 也一定可以被表示。这个性质很容易被证明。我们很容易发现,一个区间的两端点有三种情况,全为 $1$,全为 $2$ 以及一边 $1$ 一边 $2$。那么当两边存在 $2$ 时,只需要减掉这个 $2$ 即可;如果是两个 $1$,那么把这两个 $1$ 一起减掉即可。
现在我们知道了上面这个性质,开始考虑非法情况。既然 $k-2$ 可以被表示,那么我们只需要找到最大的 $k$ 就可以了。如果给出的 $k$ 比我们能找到的最大的数还大,那么这个数是不合法的。
考虑完非法情况以后,我们来考虑如何求解。我们发现,一个数减去 $2$ 后奇偶性不变,也就是说如果 $k$ 是奇数,那么我们将永远无法得到偶数,反之亦然,所以这要求我们分类讨论,分别求出最大的奇数和最大的偶数。因为题目告诉我们序列长度 $n \le 10^6$,也就是说能够被表示出来的数最多有 $2 \times 10^6$ 种。我们可以提前将这些数的左右区间都预处理出来,然后 $O(1)$ 查询即可。处理这些数的方法是将最大的奇数和偶数分别缩减,每次缩减 $2$ 并记下左右区间,按照最开始分析的性质来移动左右指针,知道两指针相遇为止。
参考代码
1 |
|
说些什么吧!