扩大
缩小

前缀和与差分

该随笔为基础内容,想要了解拓展知识可以点 这里

---算法简介

  问题一:有 $n$ 个数,现在有 $m$ 个操作,分为两种类型:

    1. 每一次要求将第 $k$ 个数加上 $a$;

    2. 查询第 $k$ 个数字的值。

  $1 ≤ k ≤ n ≤ 10^5$。

  这一题其实用一个数组就可以维护。

 

  问题二:有 $n$ 个数,并且有 $m$ 次操作,每一次操作要求查询第 $x$ 个数到第 $y$ 个数的和。

  $1 ≤ x ≤ y ≤ n,m ≤ 10^7$。

  如果用暴力或带 $\log$ 的算法做那么肯定是会 TLE 的,需要设计一个线性复杂度的算法。

  令

$$S(i)=\sum_{i=1}^na_i$$

  那么第 $x$ 到第 $y$ 个数的和就是 $S(y)-S(x-1)$。 

  而 $S(i)=S(i-1)+a_i$,所以 $S(1)$ 到 $S(n)$ 可以在 $O(n)$ 的复杂度递推出来。

  对于每次询问,便可 $O(1)$ 求出了。

 

  问题三:有已赋值的 $n$ 个数,现在有 $m$ 个指令,第 $i$ 个指令要求将第 $x_i$ 个数到第 $y_i$ 个数的每个数加上 $k$,最后求所有数的值。

  $1 ≤ x_i ≤ y_i ≤ n,m ≤ 10^7$,$1 \le k \le 10^9$。

  我们也可以用与前缀和类似的方法解决此题。

  令

$$f(i)=a_{i}-a_{i-1}$$
$$S(i)=\sum_{i=1}^nf_i$$

  然后就会发现,对于 $1 \le i \le n$ 的正整数 $i$,均有 $S(i)=a_i$。

  而当区间 $[x_i,y_i]$ 被加上相同的数时,$f$ 数组中只有 $f_{x_i}$ 和 $f_{y_i+1}$ 发生了改变。

  所以每次让区间 $[x_i,y_i]$ 每个数加上 $k$ 后,把 $f_{x_i}$ 加上 $k$,$f_{y_i+1}$减去 $k$,最后使用前缀和时这个 $k$ 就可以覆盖整个区间而不重不漏。、

  复杂度仍为 $O(n+m)$。 

该随笔为基础内容,想要了解拓展知识可以点 这里

posted @ 2019-07-31 21:29  HoshizoraZ  阅读(1069)  评论(0编辑  收藏  举报