差分

一维:

原数组:\(c[i]\)

差分数组\(a[i]\):表示\(i{\sim}n\)的数,每一个数\(c[j](i<=j<=n)\)都加上一个\(a[i]\)

应用场景:

①把从第\(k~n\)位的数都加上一个\(w\)

a[k]+=w;

②把从第\(i\)位到第\(j\)位的数都加上一个\(w\)

a[i]+=w,a[j+1]-=w;

前提是需要对数组,进行多次①②这样的操作,使用差分才有意义,不然直接暴力就可以了

要注意的是①②操作只是把那些加减操作缓存了起来,而并不是完全分布给了每一个\(c[i]\)

要把这些加减操作“落到实处“

for(int i=1;i<=n;++i)
{
  a[i]+=a[i-1];
  c[i]+=a[i];
  a[i]=0;
}

二维:

原数组:\(c[n][m]\)

差分数组:\(a[i][j]\),表示在\((i<=x<=n,j<=y<=m)\)范围内的数都加个\(a[i][j]\)

应用场景:

①把\((i<=x<=n,j<=y<=m)\)内的数都加上个\(k\)

a[i][j]+=k;

②把\((x_1<=x<=x_2,y_1<=y<=y_2)\)的数都加上\(k\)

a[x1][y1]+=k,a[x2+1][y2+1]+=k;
a[x1][y2+1]-=k,a[x2+1][y1]-=k;

把差分的操作下放到\(c[i][j]\)数组中:

for(int i=1;i<=n;++i)
  for(int j=1;j<=m;++j)
      a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1],
      c[i][j]+=a[i][j];