前缀和
规定数列{\(a_i\)}的前缀和为\(S_i\) = \(\sum{_{k = 1}^i}a_k\),常用于使用o(1)的时间计算某段区间求和
// 一维前缀和
S[i] = S[i - 1] + a[i]; //前缀和初始化,i从1开始,S[0] = 0
S[r] - s[l - 1] = a[l] + a[l + 1] + ... + a[r]; //求[l,r]区间和
// 二维前缀和
S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + a[i][j];
// 以(x1,y1)为左上角,(x2,y2)为右下角的矩阵和
S = S[x2][y2] - S[x1 - 1][y2] - S[x2][y1 - 1] + S[x1 - 1][y1 - 1];
差分
差分与前缀和相对,很显然一个数列的差分数组的前缀和数组是原数组,差分数组经常用于使用o(1)的时间对某一段区间上的所有数加上一个数c
// 一维差分
// 差分数组的构造
for(int i = 0;i < n;i ++ ) insert(i,i,a[i]) // 将初始值均为0的差分数组各个位置上插入对应的a[i]之后,该差分数组就变成了数组a的差分数组了
// 在(l,r)区间上加上c
void insert(int l,int r,int c)
{
b[l] += c,b[r + 1] -= c;
}
// 二维差分
// 差分数组的构造;
for(int i = 0;i < n;i ++ )
for(int j = 0;j < m;j ++ )
insert(i,j,i,j,a[i]);
// 在以(x1,y1)为左上角,(x2,y2)为右下角的子矩阵上的每个数上加c
void insert(int x1,int y1,int x2,int y2,int c)
{
b[x1][y1] += c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y1] -= c;
b[x2 + 1][y2 + 1] += c;
}
标签:前缀,int,差分,y1,x2,y2,模板
From: https://www.cnblogs.com/zhiao/p/17228000.html