题解:P4458 [BJOI2018] 链上二次求和

link

考虑设 \(a\) 的前缀和为 \(s\),则答案为:

\[\begin{aligned} Ans&=\sum_{i=l}^r\sum_{j=1}^{n-i+1}(s_{i+j-1}-s_{j-1})\\ &=\sum_{i=l}^r(\sum_{j=i}^ns_j-\sum_{j=0}^{n-i}s_j) \end{aligned}\]

发现这里出现了 \(s\) 的区间和,因而考虑设 \(a\) 的二阶前缀和 \(ss_i=\sum_{j=1}^is_j\),进而有:

\[\begin{aligned} Ans&=\sum_{i=l}^r(ss_n-ss_{i-1}-ss_{n-i})\\ &=(r-l+1)ss_n-\sum_{i=l-1}^{r-1}ss_{i}-\sum_{i=n-r}^{n-l}ss_i \end{aligned}\]

因此我们需要维护 \(ss\) 的区间和。考虑对 \([l,r]\) 增加 \(\Delta\)\(ss\) 的贡献。

  • 对于 \(l\le i\le r\),对 \(ss_i\) 会贡献 \(\frac{(i-l+1)(i-l+2)}{2}\Delta\)

  • 对于 \(r<i\le n\),对 \(ss_i\) 会贡献 \([\frac{(r-l+1)(r-l+2)}{2}+(r-l+1)*(i-r)]\Delta\)

线段树维护即可,时间复杂度为 \(O(q\log_2n)\)。注意 \(tag\) 可以设为 \(t_0,t_1,t_2\) 表示需要增加 \(t_2i^2+t_1i+t_0\)

posted @ 2025-02-21 14:14  FugiPig  阅读(18)  评论(0)    收藏  举报