两者之间的关系: a[n] = b[1]+b[2]+b[3]+……b[n];
a[n]是前缀和;
b[n]是差分;

tip : 两个数组本没有时时联动关系,对某一数组操作以后需要通过手动操作同步
考虑更新

在题目中,前缀和 就是 根据a[n] 构造一个 其前n项和 a[n] ;
差分 是 构造一个b[n] 让a[n] 是他的前n项和 ;

前缀和n

一维

类似数列

  1. S[i] = a[1] + a[2] + ... a[i];
  2. a[l] + ... + a[r] = S[r] - S[l - 1];
  3. //最最重要的是思想
  4. for(int i=1;i<=n;i++)
  5. S[i] = S[i-1]+a[i];
  6. //每个i都有其对应的前缀和

二维

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];

for(int i=1;i<=n;i++)
  for(int i=1;i<=m;i++)
  {
    s[i][j] = s[i-1][j]+s[i][j-1]-s[i-1][j-1];
  }

差分

差分就一个思想 插入

一维

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

void insert(int l,int r,int c)
{
    b[l]+=c;
    b[r+1]-=c;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);

    for(int i=1;i<=n;i++) insert(i,i,a[i]);

    while (m -- )
    {
        int l,r,c;
        scanf("%d%d%d",&l,&r,&c);
        insert(l,r,c);
    }
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        sum+=b[i];
        a[i]=sum;
       //b[i]+=b[i-1];
    }
    for(int i=1;i<=n;i++) printf("%d ",a[i]);
    return 0;
}

二维

给以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵中的所有元素加上c:
S[x1, y1] += c, S[x2 + 1, y1] -= c, S[x1, y2 + 1] -= c, S[x2 + 1, 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 main()
{
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++) insert(i,j,i,j,a[i][j]);
    while(q--)
    {
        int x1,y1,x2,y2,c;
        scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&c);
        insert(x1,y1,x2,y2,c);
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)  b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];
        //上面就很巧妙
        for (int i = 1; i <= n; i ++ )
    {
        for (int j = 1; j <= m; j ++ ) printf("%d ", b[i][j]);
        puts("");
    }

    return 0;
}