赞
踩
a[i][j]
,若要给a[i][j]
中以(x1,y1)
和(x2,y2)
为对角线的子矩阵中每个数都加上一个常数c
,暴力的做法时间复杂度为O(N^2)
,使用二维差分可以在O(1)
的时间复杂度内完成该操作b[i][j]
使得原二维数组a[i][j]
是二维数组b[i][j]
的二维前缀和数组,即满足:a[i][j]
中以(x1,y1)
和(x2,y2)
为对角线的子矩阵中每个数都加上一个常数c
,等价于对b[i][j]
数组进行如下操作:
b[x1][y1] += c
b[x2+1][y2+1] += c
b[x2+1][y1] -= c
b[x1][y2+1] -= c
//使原数组a[i][j]中以(x1,y1)和(x2,y2)为对角线的子矩阵中每个数都加上一个常数c
//接口可以用于构造差分矩阵以及进行原数组的矩阵元素整体修改操作
void Matrix_Add(long long(*b)[1010],int x1 ,int y1,int x2 ,int y2,int c){
b[x1][y1] += c;
b[x2+1][y2+1] += c;
b[x1][y2+1] -= c;
b[x2+1][y1] -= c;
}
//状态递推法对b[i][j]数组求二维前缀和,以获取原数组的元素--> 默认矩阵第0行第0列全部元素为0
void Get_Pre_Sum(long long(*b)[1010],int row , int col){
//求(1,1)~(i,j)的子矩阵的和
for(int i = 1 ; i <= row ; ++i){
for(int j = 1 ; j<=col ; ++j){
b[i][j] += (b[i-1][j] + b[i][j-1] - b[i-1][j-1]);
}
}
}
b[i][j]
数组的二维前缀和就可以恢复原数组a[i][j]
void Get_Pre_Sum(vector<vector<vector<long long>>>& Board,int high,int row,int col ){
for(int i = 1 ; i <= high ; ++i){
for(int j = 1 ; j <= row ; ++j){
for(int k = 1 ; k <= col ; ++k){
Board[i][j][k] += Board[i-1][j][k] + Board[i][j-1][k] - Board[i-1][j-1][k] +
Board[i][j][k-1] - Board[i-1][j][k-1] - Board[i][j-1][k-1] + Board[i-1][j-1][k-1];
}
}
}
}
相邻互斥,相间相容
void Matrix_Add(vector<vector<vector<long long>>>& Board,int x1 , int y1 , int z1 , int x2 , int y2 , int z2 , int c){
Board[x1][y1][z1] += c;
Board[x1][y2+1][z1] -= c;
Board[x2+1][y1][z1] -= c;
Board[x2+1][y2+1][z1] += c;
Board[x1][y1][z2+1] -= c;
Board[x1][y2+1][z2+1] += c;
Board[x2+1][y1][z2+1] += c;
Board[x2+1][y2+1][z2+1] -= c;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。