Warning
本文发布于 2022/07/31,内容可能已过时。
小算法
ACM
快读快写
头模板
复杂度
前缀和与差分
题目要求: 对长为 n 的数组进行 m 次查询:求 $[l, r]$ 之间的和
- 如果是暴力遍历,则最坏可达到 $O(n * m)$
- 前缀和主要应用在对给定数组进行离线求和,与求区间和。离线在于预先遍历求一次和后,之后就可以直接读取了, 复杂度为 $O(n)$
此时,前 n 项和为:sum[n]
,$[l ,r]$ 之间的和为 sum[r] - sum[l - 1]
差分
如给数组 [l, r]
之间加上 c
树状数组
前缀和对于一次求和(n)多次查询很快,就 $O(n)$;但对于修改值后再查询却可能高达 $O(n^2)$,因为每次修改后还要再求前缀和
而树状数组对于修改和查询都是 $O(\log_2{n})$,因此整体就 $O(m\log_2{n})$
树状数组要做的就是,对数组进行单点或区间修改,并进行单点或区间查询和
树状数组的结构就是将完全二叉树用数组来表示
以数组 $Arr = {8,6,1,4,5,5,1,1,3,2,1,4,9,0,7,4}$ 为例
树状数组的几种变式
单点更新,区间查询
题目要求: 对数组进行 T 次操作,输入 3 个数字,分别表示:
1 x k
含义:将第 $x$ 个数加上 $k$
2 x y
含义:输出区间 $[x,y]$ 内每个数的和
区间更新,区间查询
题目要求 变成了是在 $[l, r]$ 内增加 k,并求区间内的和
很难不想到利用 差分 来进行区间更新,那么:
线段树
参考