#然而还是没能日更博客#
# 题目
给出一个长度为 $n$ 的正整数数列 $A$,回答 $m$ 次询问:
每次询问给定整数 $L,R,P$,求区间 $[L,R]$ 中的一个子区间 $[L’,R’]$,使得 $\left(\sum_{i=L’}^{R’}A_i\right)\bmod P$ 最小,输出该最小值。
数据规模:$1\le n,m\le 10^4$;$1\le P\le3\times10^4$;$0\le A_i\le 10^9$。
# 解析
首先可以想到的是暴力枚举 $[L’,R’]$,然后用前缀和求出区间和,取模后取 min 即可。复杂度 $O(n^2m)$
然后考虑只枚举一个端点,另一个端点直接计算(也是较常规的套路了),这里考虑枚举右端点(左端点也可以)。
记前缀和为 $S$,那么对于每一个 $R’$,要求出一个 $L’$ 使得 $(S_{R’}-S_{L’})\bmod P$ 最小。麻烦在于这个 $\bmod P$,但是稍加思索可以发现一个结论:
使得 $(S_{R’}-S_{L’})\bmod P$ 最小的 $L’$ 一定满足 $S_{R’}\bmod P\ge S_{L’}\bmod P$
> 证明
如果 $S_{R’}\bmod P<S_{L’}\bmod P$,那么 $S_{R’}\bmod P<(S_{R’}-S_{L’})\bmod P$,看上面右图就可以发现了。那么 $L’$ 如果取 $R’$ 会更优一些。
那就方便了,我们相当于要找不超过 $(S_{R’}\bmod P)$ 的最大的 $(S_{L’}\bmod P)$,这个可以 $R’$ 从左到右扫一遍,用平衡树来维护前驱。
# 源代码
1 | /*Lucky_Glass*/ |
The End
Thanks for reading!
-“如你所愿”