差分 一维差分 二维差分 差分数组意义 前缀和 一维前缀和 二维前缀和
最大难点在于 二维差分数组的理解
二维差分数组d[x][y] 不是指 a数组中具体某两个值的差值.
d数组用于统计二维矩阵值的更新,是我告诉你某个子矩阵都要加个p,然后用d数组来让这个子矩阵每个值都加上p的.
学习需要循序渐进,读者且看文章娓娓道来.
//一维差分,摘自https://blog.csdn.net/Healer66/article/details/87201014
//简单验证如下
a[1],a[2],a[3],a[4],a[5] a[]为原始数列
b[1],b[2],b[3],b[4],b[5],b[6] b[]为差分数列
b[1]=a[1]-0
b[2]=a[2]-a[1]
b[3]=a[3]-a[2]
b[4]=a[4]-a[3]
b[5]=a[5]-a[4]
b[6]=0-a[5]
性质1
a[1]=b[1]
a[2]=b[2]+b[1]
a[3]=b[3]+b[2]+b[1]
a[4]=b[4]+b[3]+b[2]+b[1]
a[5]=b[5]+b[4]+b[3]+b[2]+b[1]
性质2
L=2,R=4
a[1],a[2]+1,a[3]+1,a[4]+1,a[5] a[]+1为原始数列,每个元素+1
b'[1],b'[2],b'[3],b'[4],b'[5],b'[6] b'[]为新的差分数列
b'[1]=a[1]-0=b[1]
b'[2]=(a[2]+1)-a[1]=b[2]+1
b'[3]=(a[3]+1)-(a[2]+1)=b[3]
b'[4]=(a[4]+1)-(a[3]+1)=b[4]
b'[5]=a[5]-(a[4]+1)=b[5]-1
b'[6]=0-a[5]=b[6]
//二维差分,摘自https://www.cnblogs.com/LMCC1108/p/10753451.html修改了小错误
//以下为二维差分模拟过程 a[i][j]子矩阵(3,3)-(4,4)区间每个元素+1 采用 二维差分数组 进行后续计算
a[i][j]
sum[i][j]
sum[i][j]的生成代码如下
#include <stdio.h>
#include <string.h>
#define maxn 10
int a[maxn][maxn],sum[maxn][maxn],d[maxn][maxn];
int main(){
int i,j;
for(i=1;i<=6;i++)
for(j=1;j<=6;j++)
a[i][j]=1;//a[i][j]矩阵建立
memset(sum,0,sizeof(sum));
for(i=1;i<=6;i++)
for(j=1;j<=6;j++)
sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+a[i][j];//二维前缀和
for(i=1;i<=6;i++){
for(j=1;j<=6;j++)
printf("%d\t",sum[i][j]);
printf("\n");
}
return 0;
}
a[i][j]子矩阵(3,3)-(4,4)区间每个元素+1
对应的二维差分矩阵d[i][j]
二维差分矩阵d[i][j]的生成代码如下
#include <stdio.h>
#include <string.h>
#define maxn 10
int a[maxn][maxn],sum[maxn][maxn],d[maxn][maxn];
int main(){
int i,j;
for(i=1;i<=6;i++)
for(j=1;j<=6;j++)
a[i][j]=1;//a[i][j]矩阵建立
memset(d,0,sizeof(d));
d[3][3]+=1,d[3][4+1]-=1,d[4+1][3]-=1,d[4+1][4+1]+=1;//a[i][j]子矩阵(3,3)-(4,4)区间每个元素+1 二维差分数组建立
for(i=1;i<=7;i++)
for(j=1;j<=7;j++)
d[i][j]+=d[i][j-1]+d[i-1][j]-d[i-1][j-1];//二维差分数组建立
for(i=1;i<=7;i++){
for(j=1;j<=7;j++)
printf("%d\t",d[i][j]);
printf("\n");
}
return 0;
}
更新后的a[i][j]矩阵
由二维差分数组d得到更新的a矩阵代码如下
#include <stdio.h>
#include <string.h>
#define maxn 10
int a[maxn][maxn],sum[maxn][maxn],d[maxn][maxn];
int main(){
int i,j;
for(i=1;i<=6;i++)
for(j=1;j<=6;j++)
a[i][j]=1;//a[i][j]矩阵建立
memset(d,0,sizeof(d));
d[3][3]+=1,d[3][4+1]-=1,d[4+1][3]-=1,d[4+1][4+1]+=1;//a[i][j]子矩阵(3,3)-(4,4)区间每个元素+1 二维差分数组建立
for(i=1;i<=7;i++)
for(j=1;j<=7;j++)
d[i][j]+=d[i][j-1]+d[i-1][j]-d[i-1][j-1];//二维差分数组建立
for(i=1;i<=6;i++)
for(j=1;j<=6;j++)
a[i][j]+=d[i][j];//a[i][j]矩阵的更新
for(i=1;i<=6;i++){
for(j=1;j<=6;j++)
printf("%d\t",a[i][j]);
printf("\n");
}
return 0;
}
更新的sum矩阵如下
由二维差分数组d得到更新的sum矩阵代码如下 2019-8-18 10:42
#include <stdio.h>
#include <string.h>
#define maxn 10
int a[maxn][maxn],sum[maxn][maxn],d[maxn][maxn];
int main(){
int i,j;
for(i=1;i<=6;i++)
for(j=1;j<=6;j++)
a[i][j]=1;//a[i][j]矩阵建立
memset(d,0,sizeof(d));
d[3][3]+=1,d[3][4+1]-=1,d[4+1][3]-=1,d[4+1][4+1]+=1;//a[i][j]子矩阵(3,3)-(4,4)区间每个元素+1 二维差分数组建立
for(i=1;i<=7;i++)
for(j=1;j<=7;j++)
d[i][j]+=d[i][j-1]+d[i-1][j]-d[i-1][j-1];//二维差分数组建立
for(i=1;i<=6;i++)
for(j=1;j<=6;j++)
a[i][j]+=d[i][j];//a[i][j]矩阵的更新
memset(sum,0,sizeof(sum));
for(i=1;i<=6;i++)
for(j=1;j<=6;j++)
sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+a[i][j];//二维前缀和
for(i=1;i<=6;i++){
for(j=1;j<=6;j++)
printf("%d\t",sum[i][j]);
printf("\n");
}
return 0;
}
好比写名字,一笔一划是普通算法,敲图章是差分算法.2019-8-18 10:50