天天看點

二維差分和三維差分二維差分(差分與字首和的下标都從1開始,避免出現越界)題目描述:最後再使用二維字首和即可求得答案三維差分公式:

二維差分(差分與字首和的下标都從1開始,避免出現越界)

題目描述:

輸入一個n行m列的整數矩陣,再輸入q個操作,每個操作包含五個整數x1, y1, x2, y2, c,其中(x1, y1)和(x2, y2)表示一個子矩陣的左上角坐标和右下角坐标。

每個操作都要将選中的子矩陣中的每個元素的值加上c。

請你将進行完所有操作後的矩陣輸出。

輸入格式

第一行包含整數n,m,q。

接下來n行,每行包含m個整數,表示整數矩陣。

接下來q行,每行包含5個整數x1, y1, x2, y2, c,表示一個操作。

輸出格式

共 n 行,每行 m 個整數,表示所有操作進行完畢後的最終矩陣。

資料範圍

1≤n,m≤1000

1≤q≤100000

1≤x1≤x2≤n

1≤y1≤y2≤m

−1000≤c≤1000

−1000≤矩陣内元素的值≤1000

輸入樣例:

3 4 3

1 2 2 1

3 2 2 1

1 1 1 1

1 1 2 2 1

1 3 2 3 2

3 1 3 4 1

輸出樣例:

2 3 4 1

4 3 4 1

2 2 2 2

算法公式:在x1,y1,x2,y2,區間内+x就是sum[x1][y1]+=w、 sum[x2+1][y1]-=w、sum[x1][y2+1]-=w、sum[x2+1][y2+1]+=w。

圖解:

想在黃色區間内+x,則要在sum[x1][y1]+=w

二維差分和三維差分二維差分(差分與字首和的下标都從1開始,避免出現越界)題目描述:最後再使用二維字首和即可求得答案三維差分公式:

但是 會影響綠色區間以及藍色區間,是以需要減掉 sum[x2+1][y1]-=w、sum[x1][y2+1]-=w。

二維差分和三維差分二維差分(差分與字首和的下标都從1開始,避免出現越界)題目描述:最後再使用二維字首和即可求得答案三維差分公式:
二維差分和三維差分二維差分(差分與字首和的下标都從1開始,避免出現越界)題目描述:最後再使用二維字首和即可求得答案三維差分公式:

但是黑色區間被減了兩次,是以需要加回一次,sum[x2+1][y2+1]+=w

二維差分和三維差分二維差分(差分與字首和的下标都從1開始,避免出現越界)題目描述:最後再使用二維字首和即可求得答案三維差分公式:

最後再使用二維字首和即可求得答案

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
namespace IO{
    inline LL read(){
        LL o=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){o=o*10+c-'0';c=getchar();}
        return o*f;
    }
}using namespace IO;
const int N=1e3+7,base=1e9;
int sum[N][N];
void Insert(int x1,int y1,int x2,int y2,int x){//二維差分
    sum[x1][y1]+=x;
    sum[x2+1][y1]-=x;
    sum[x1][y2+1]-=x;
    sum[x2+1][y2+1]+=x;
}
int main(){
    int n,m,k;
    n=read(),m=read(),k=read();
    for(int i=1;i<=n;i++){
        for(int x,j=1;j<=m;j++){
            x=read();
            Insert(i,j,i,j,x);//在目前位置插入,就在目前位置的下一個位置減去貢獻
        }
    }
    int x1,x2,y1,y2,x;
    while(k--){
        x1=read(),y1=read(),x2=read(),y2=read(),x=read();
        Insert(x1,y1,x2,y2,x);//差分
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){//二維字首和
            sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
            printf("%d ",sum[i][j]);
        }
        printf("\n");
    }
    return 0;
}

           

三維差分公式:

PS:與二維差分思路差不多

b(x1, y1, z1) -=h

b(x1, y1, z2+1) +=h

b(x1, y2+1, z1) +=h

b(x1, y2+1, z2+1) -=h

b(x2+1, y1, z1) +=h

b(x2+1, y1, z2+1) -=h

b(x2+1, y2+1, z1) -=h

b(x2+1, y2+1, z2+1) +=h

繼續閱讀