一维差分和二维差分
差分
一维:
原数组:\(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];