前缀和/差分
1. 前缀和
\(\mathcal{O}(n)\) 预处理,多次 \(\mathcal{O}(1)\) 查询。
1.1 一维前缀和
给你一个 \(n\) 个数的序列 \(a\),多次查询 \(l \sim r\) 的和。
维护 \(b_i=\sum\limits_{i=1}^{i} a_i\),查询区间 \(l \sim r\) 的和就是 \(b_r-b_{l-1}\)。
1.2 二维前缀和
给你一个 \(n\) 行 \(m\) 列的矩阵 \(a\)。接下来有 \(q\) 次查询,给定参数 \(x_1,y_1,x_2,y_2\)。请输出以 \((x_1, y_1)\) 为左上角, \((x_2,y_2)\) 为右下角的子矩阵的和。
设 \(b_{i,j}\) 为 \((1,1)\sim (i,j)\) 这个矩阵的和,由容斥原理,可得递推式 \(b_{i,j}=b_{i-1,j}+b_{i,j-1}-b_{i-1,j-1}+a_{i,j}\)。
如果要求 \((x_1,y_1)~(x_2,y_2)\) 的矩阵和,那么 \(ans=b_{x_2,y_2}-b_{x_1-1,y_2}-b_{x_2,y_1-1}+b_{x_1-1,x_2-1}\)。
2. 差分
支持 \(\mathcal{O}(1)\) 修改,最后 \(\mathcal{O}(n)\) 查询。
1.1 一维差分
给你一个 \(n\) 个数的序列 \(b\),每次操作令 \(l \sim r\) 集体加上 \(v\),最后求序列 \(a\)。
设 \(a_i=\left\{ \begin{array}{} 0 & i=1 \\ b_i-b_{i-1} & i>1 \end{array}\right.\),令 \(l \sim r\) 集体加上 \(v\) 就是 \(a_l+v\),\(a_{r+1}-v\),最后对 \(a\) 做一遍前缀和就得到了最终结果,这是因为前缀和和差分是互逆运算。
1.2 二维差分
给你一个 \(n\) 行 \(m\) 列的矩阵 \(b\)。\(q\) 次操作,每次给定参数 \(x1,y1,x2,y2,v\),将子矩阵 \((x_1,y_1)\sim (x_2,y_2)\) 加上 \(v\),最后输出矩阵 \(b\)。
由于前缀和和差分是互逆运算,设 \(a\) 为 \(b\) 的差分数组,对前缀和的递推式做代数变换可得 \(a_{i,j}=b_{i,j}+b_{i-1,j-1}-b_{i-1,j}-b_{i,j-1}\)。
将子矩阵 \((x_1,y_1)\sim (x_2,y_2)\) 加上 \(v\),其实就等价于
最后对于 \(a\) 数组做一遍前缀和就可以得到 \(b\) 数组了。
二维前缀和/差分看起来很麻烦但其实画个图很好理解。
                    
                
                
            
        
浙公网安备 33010602011771号