前缀和及差分原理和应用

前缀和

前缀和的思路是这样的,对于一个给定的数组 a,我们额外开辟一个前缀和数组进行预处理:

前缀和 sum[i]代表【1~i】的a的和。

推导如下:

前缀和及差分原理和应用_第1张图片

前缀和应用

求任一子区间的和。
且S【0】 = 0 ,数字的序号从1开始。这样任何 第l个数字 到 第r个数字的和为:

S【r】 - s【l-1】 = a【l】+ … + a【r】

模板

S[i] = a[1] + a[2] + ... a[i]
a[l] + ... + a[r] = S[r] - S[l - 1]				

二维数组前缀和

和一维前缀和类似。

  • 可以求连续子区间的和。
  • 但是需要减去重合的部分。

模板

S[i, j] = 第i行j列格子左上部分所有元素的和
以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和为:
S[x2, y2] - S[x1 - 1, y2] - S[x2, y1 - 1] + S[x1 - 1, y1 - 1]

差分

差分就是将数列中的每一项分别与前一项数做差。

性质:

1、差分序列求前缀和可得原序列

2、将原序列区间[L,R]中的元素全部+1,可以转化操作为差分序列L处+1,R+1处-1

3、按照性质2得到,每次修改原序列一个区间+1,那么每次差分序列修改处增加的和减少的相同

差分数组构造

需要d[i]满足:a【i】= d【1】+ d 【2】+ …+d【i】

差分就是将数列中的每一项分别与前一项数做差,也就是 d[i] = a[i] - a[i-1]

差分应用——区间修改 ----- O(1)复杂度

  • [2,4]上加上5。
  • d数组上只有d[2]和d[5]被改变了。
  • [2,4]上加上5。只需要
    • d[l] += 5
    • d[r+1] -= 5
  • 然后a【i】= d【1】+ d 【2】+ …+d【i】

前缀和及差分原理和应用_第2张图片

那么代码为:

给区间[l, r]中的每个数加上c可以转化为:B[l] += c, B[r + 1] -= c

解释下 B[l] += c, B[r + 1] -= c.

  • B[l] += c 代表(l,正无穷)的点都加上了c
  • B[r + 1] -= c代表(r+1,正无穷)的点都减去了c

差分构造模板

 for(int i=1;i<=n;i++) cin>>a[i];//读取原序列的值
    //构造差分序列 由b[i]=a[1]+a[2]+...+a[i]得出b[i]=a[i]-a[i-1]
    for(int i=1;i<=n;i++) b[i]=a[i]-a[i-1];

差分例题

有一个数列,询问m次。

讲【l,r】上添加上一个数c.

最后问这个数组是什么

#include
using namespace std;
const int N=100010;
int a[N],b[N];//a[N]为原序列  b[N]为差分序列
int main()
{
    //前缀和的差分=原序列 差分的前缀和=原序列,
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];//读取原序列的值
    //构造差分序列 由b[i]=a[1]+a[2]+...+a[i]得出b[i]=a[i]-a[i-1]
    for(int i=1;i<=n;i++) b[i]=a[i]-a[i-1];
    while(m--)//对差分序列进行处理
    {
        int l,r,c;
        cin>>l>>r>>c;
        b[l]+=c;
        b[r+1]-=c;
    }
    for(int i=1;i<=n;i++)//对差分序列进行求和来获得原序列,∵差分序列的前缀和=原序列
    {
        b[i]+=b[i-1];//s[i]=s[i-1]+a[i]
        cout<<b[i]<<" ";
    }
    return 0;
}

二维差分 —— 模板题 AcWing 798. 差分矩阵

若二维差分数组为b[N][N].类比一维差分,则:

  • b[x1][y1]+=c代表以(x1,y1)为左上角,(正无穷,正无穷)为右下角构成矩形的点都加上c
    给以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵中的所有元素加上c:
    b[x1, y1] += c, b[x2 + 1, y1] -= c, b[x1, y2 + 1] -= c, b[x2 + 1, y2 + 1] += c

我们需要构造一个b数组,使得b的前缀和为a数组。
前缀和及差分原理和应用_第3张图片

你可能感兴趣的:(算法,前缀和及差分,算法,前缀和,差分)