差分 一维差分 二维差分 差分数组意义 前缀和 一维前缀和 二维前缀和

差分   一维差分   二维差分   差分数组意义 前缀和   一维前缀和   二维前缀和

最大难点在于   二维差分数组的理解

二维差分数组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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值