\(\text{Description}\)

传送门

\(\text{Solution}\)

先看看一个简单的问题:

给定序列 \(a\),有单点修改,查询 \(s_i\)\(s_i\) 是前缀和)。

这个问题应该有两种解决方法:

  1. 单点修改,再 \([1,i]\) 区间查询。
  2. 考虑每个点修改对前缀和的贡献,显然只会对 \([i,n]\)\(val_{now}-val_{past}\) 的影响,这是区间修改。最后单点查询。

本质就是维护单点和维护前缀和。注意第一种方法只能查询一次前缀和,而第二种方法可以查询一段区间的前缀和。

尝试优化我们的查询方式。

发现有(即每一种元素往后的贡献):

\[SS_i=\sum_{j=1}^i(i-j+1)\times a_j \]

由于 \(i\) 是查询,\(j\) 是插入,\(i,j\) 是不相关的,我们得分开维护。

就有:

\[SS_i=i\times \sum_{j=1}^i a_j-\sum_{j=1}^i (j-1)\times a_j \]

分别维护 \(a_j\) 序列与 \((j-1)\times a_j\) 序列即可。

我们需要查询 \([1,i]\) 的前缀和,所以用法二维护即可(就是把最后的查询变成区间查询)。

\(\text{Code}\)

咕咕咕...
posted on 2021-01-02 12:17  Oxide  阅读(65)  评论(0)    收藏  举报