给定大小为N*M的二维矩阵mat[][]和{x1, y1, x2, y2, K}形式的Q查询。对于每个查询,任务是将值K添加到从单元格(x1, y1)到(x2, y2) 的子矩阵中。在执行完所有查询后打印矩阵。
例子:
Input: N = 3, M = 4, mat[][] = {{1, 0, 1, 2}, {0, 2, 4, 1}, {1, 2, 1, 0}}, Q = 1, Queries[][] = {{0, 0, 1, 1, 2}}
Output:
3 2 1 2
2 4 4 1
1 2 1 0
Explanation:
There is only one query i.e., updating the submatrix from cell mat[0][0] to mat[1][1] by increment of 2, the matrix becomes:
3 2 1 2
2 4 4 1
1 2 1 0
Input: N = 2, M = 3, mat[][] = {{3, 2, 1}, {2, 4, 4}}, Q = 1, Queries[][] = { {0, 1, 1, 2, -1}, {0, 0, 1, 1, 5}}
Output:
8 6 0
7 8 3
Explanation:
For query 1, i.e., updating the submatrix from cell mat[0][1] to mat[1][2] by increment of (-1), the matrix becomes:
3 1 0
2 3 3
For query 2, i.e., updating the submatrix from cell mat[0][0] to mat[2][2] by increment of 5, the matrix becomes:
8 6 0
7 8 3
朴素的方法:最简单的方法是迭代子矩阵并将K添加到每个查询从mat[x1][y1]到mat[x2][y2] 的所有元素。上述操作后打印矩阵。
时间复杂度: O(N*M*Q)
辅助空间: O(1)
高效方法:思想是使用辅助矩阵对子矩阵单元格的角执行更新操作,然后找到矩阵的前缀和以获得结果矩阵。以下是步骤:
- 初始化辅助矩阵发言权的所有元素AUX [] []为0。
- 对于每个查询{x1, y1, x2, y2, K}更新辅助矩阵为:
- 辅助[x1][y1] += K
- if(x2 + 1 < N) 然后 aux[x2 + 1][y1] -= K
- if(x2 + 1 < N && y2 + 1 < N) 那么 aux[x2 + 1][y2 + 1] += K
- if(y2 + 1 < N) 然后 aux[x1][y2 + 1] -= K
- 求辅助矩阵每一行的前缀和。
- 求辅助矩阵每一列的前缀和。
- 现在,将辅助矩阵更新为辅助矩阵和给定矩阵的每个相应单元格中元素的总和。
- 完成上述所有操作后打印辅助矩阵。
Below is the illustration for how auxiliary matrix is created and updated for query[][] = {{0, 0, 1, 1, 2}, {0, 1, 2, 3, -1}}:
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
#define N 3
#define M 4
// Query data type
struct query {
int x1, x2, y1, y2, K;
};
// Function to update the given query
void updateQuery(int from_x, int from_y,
int to_x, int to_y,
int k, int aux[][M])
{
// Update top cell
aux[from_x][from_y] += k;
// Update bottom left cell
if (to_x + 1 < N)
aux[to_x + 1][from_y] -= k;
// Update bottom right cell
if (to_x + 1 < N && to_y + 1 < M)
aux[to_x + 1][to_y + 1] += k;
// Update top right cell
if (to_y + 1 < M)
aux[from_x][to_y + 1] -= k;
}
// Function that updates the matrix
// mat[][] by adding elements of aux[][]
void updateMatrix(int mat[][M], int aux[][M])
{
// Compute the prefix sum of all columns
for (int i = 0; i < N; i++) {
for (int j = 1; j < M; j++) {
aux[i][j] += aux[i][j - 1];
}
}
// Compute the prefix sum of all rows
for (int i = 0; i < M; i++) {
for (int j = 1; j < N; j++) {
aux[j][i] += aux[j - 1][i];
}
}
// Get the final matrix by adding
// mat and aux matrix at each cell
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
mat[i][j] += aux[i][j];
}
}
}
// Function that prints matrix mat[]
void printMatrix(int mat[][M])
{
// Traverse each row
for (int i = 0; i < N; i++) {
// Traverse each columns
for (int j = 0; j < M; j++) {
cout << mat[i][j] << " ";
}
cout << "\n";
}
}
// Function that performs each query in
// the given matrix and print the updated
// matrix after each operation performed
void matrixQuery(int mat[][M], int Q,
query q[])
{
// Initialize all elements to 0
int aux[N][M] = {};
// Update auxiliary matrix
// by traversing each query
for (int i = 0; i < Q; i++) {
// Update Query
updateQuery(q[i].x1, q[i].x2,
q[i].y1, q[i].y2,
q[i].K, aux);
}
// Compute the final answer
updateMatrix(mat, aux);
// Print the updated matrix
printMatrix(mat);
}
// Driver Code
int main()
{
// Given Matrix
int mat[N][M] = { { 1, 0, 1, 2 },
{ 0, 2, 4, 1 },
{ 1, 2, 1, 0 } };
int Q = 1;
// Given Queries
query q[] = { { 0, 0, 1, 1, 2 } };
// Function Call
matrixQuery(mat, Q, q);
return 0;
}
Java
// Java program for the above approach
class GFG{
static final int N = 3;
static final int M = 4;
// Query data type
static class query
{
int x1, x2, y1, y2, K;
public query(int x1, int x2,
int y1, int y2, int k)
{
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
K = k;
}
};
// Function to update the given query
static void updateQuery(int from_x, int from_y,
int to_x, int to_y,
int k, int aux[][])
{
// Update top cell
aux[from_x][from_y] += k;
// Update bottom left cell
if (to_x + 1 < N)
aux[to_x + 1][from_y] -= k;
// Update bottom right cell
if (to_x + 1 < N && to_y + 1 < M)
aux[to_x + 1][to_y + 1] += k;
// Update top right cell
if (to_y + 1 < M)
aux[from_x][to_y + 1] -= k;
}
// Function that updates the matrix
// mat[][] by adding elements of aux[][]
static void updateMatrix(int mat[][],
int aux[][])
{
// Compute the prefix sum of all columns
for (int i = 0; i < N; i++)
{
for (int j = 1; j < M; j++)
{
aux[i][j] += aux[i][j - 1];
}
}
// Compute the prefix sum of all rows
for (int i = 0; i < M; i++)
{
for (int j = 1; j < N; j++)
{
aux[j][i] += aux[j - 1][i];
}
}
// Get the final matrix by adding
// mat and aux matrix at each cell
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
mat[i][j] += aux[i][j];
}
}
}
// Function that prints matrix mat[]
static void printMatrix(int mat[][])
{
// Traverse each row
for (int i = 0; i < N; i++)
{
// Traverse each columns
for (int j = 0; j < M; j++)
{
System.out.print(mat[i][j] + " ");
}
System.out.print("\n");
}
}
// Function that performs each query in
// the given matrix and print the updated
// matrix after each operation performed
static void matrixQuery(int mat[][],
int Q, query q[])
{
// Initialize all elements to 0
int [][]aux = new int[N][M];
// Update auxiliary matrix
// by traversing each query
for (int i = 0; i < Q; i++)
{
// Update Query
updateQuery(q[i].x1, q[i].x2,
q[i].y1, q[i].y2,
q[i].K, aux);
}
// Compute the final answer
updateMatrix(mat, aux);
// Print the updated matrix
printMatrix(mat);
}
// Driver Code
public static void main(String[] args)
{
// Given Matrix
int mat[][] = {{1, 0, 1, 2},
{0, 2, 4, 1},
{1, 2, 1, 0}};
int Q = 1;
// Given Queries
query q[] = {new query(0, 0, 1, 1, 2 )};
// Function Call
matrixQuery(mat, Q, q);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program for the above approach
# Query data type
# Function to update the given query
def updateQuery(from_x, from_y,
to_x, to_y, k, aux):
# Update top cell
aux[from_x][from_y] += k
# Update bottom left cell
if (to_x + 1 < 3):
aux[to_x + 1][from_y] -= k
# Update bottom right cell
if (to_x + 1 < 3 and to_y + 1 < 4):
aux[to_x + 1][to_y + 1] += k
# Update top right cell
if (to_y + 1 < 4):
aux[from_x][to_y + 1] -= k
# return aux
# Function that updates the matrix
# mat[][] by adding elements of aux[][]
def updatematrix(mat, aux):
# Compute the prefix sum of all columns
for i in range(3):
for j in range(1, 4):
aux[i][j] += aux[i][j - 1]
# Compute the prefix sum of all rows
for i in range(4):
for j in range(1, 3):
aux[j][i] += aux[j - 1][i]
# Get the final matrix by adding
# mat and aux matrix at each cell
for i in range(3):
for j in range(4):
mat[i][j] += aux[i][j]
# return mat
# Function that prints matrix mat[]
def printmatrix(mat):
# Traverse each row
for i in range(3):
# Traverse each columns
for j in range(4):
print(mat[i][j], end = " ")
print()
# Function that performs each query in
# the given matrix and print the updated
# matrix after each operation performed
def matrixQuery(mat, Q, q):
# Initialize all elements to 0
aux = [[ 0 for i in range(4)]
for i in range(3)]
# Update auxiliary matrix
# by traversing each query
for i in range(Q):
# Update Query
updateQuery(q[i][0], q[i][1],
q[i][2], q[i][3],
q[i][4], aux)
# Compute the final answer
updatematrix(mat, aux)
# Print the updated matrix
printmatrix(mat)
# Driver Code
if __name__ == '__main__':
# Given 4atrix
mat = [ [ 1, 0, 1, 2 ],
[ 0, 2, 4, 1 ],
[ 1, 2, 1, 0 ] ]
Q = 1
# Given Queries
q = [ [0, 0, 1, 1, 2 ] ]
# Function Call
matrixQuery(mat, Q, q)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
class GFG{
static readonly int N = 3;
static readonly int M = 4;
// Query data type
class query
{
public int x1, x2, y1, y2, K;
public query(int x1, int x2,
int y1, int y2,
int k)
{
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
K = k;
}
};
// Function to update the given query
static void updateQuery(int from_x, int from_y,
int to_x, int to_y,
int k, int [,]aux)
{
// Update top cell
aux[from_x, from_y] += k;
// Update bottom left cell
if (to_x + 1 < N)
aux[to_x + 1, from_y] -= k;
// Update bottom right cell
if (to_x + 1 < N && to_y + 1 < M)
aux[to_x + 1, to_y + 1] += k;
// Update top right cell
if (to_y + 1 < M)
aux[from_x, to_y + 1] -= k;
}
// Function that updates the matrix
// [,]mat by adding elements of aux[,]
static void updateMatrix(int [,]mat,
int [,]aux)
{
// Compute the prefix sum of all columns
for(int i = 0; i < N; i++)
{
for(int j = 1; j < M; j++)
{
aux[i, j] += aux[i, j - 1];
}
}
// Compute the prefix sum of all rows
for(int i = 0; i < M; i++)
{
for(int j = 1; j < N; j++)
{
aux[j, i] += aux[j - 1, i];
}
}
// Get the readonly matrix by adding
// mat and aux matrix at each cell
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
mat[i, j] += aux[i, j];
}
}
}
// Function that prints matrix []mat
static void printMatrix(int [,]mat)
{
// Traverse each row
for(int i = 0; i < N; i++)
{
// Traverse each columns
for(int j = 0; j < M; j++)
{
Console.Write(mat[i, j] + " ");
}
Console.Write("\n");
}
}
// Function that performs each query in
// the given matrix and print the updated
// matrix after each operation performed
static void matrixQuery(int [,]mat,
int Q, query []q)
{
// Initialize all elements to 0
int [,]aux = new int[N, M];
// Update auxiliary matrix
// by traversing each query
for(int i = 0; i < Q; i++)
{
// Update Query
updateQuery(q[i].x1, q[i].x2,
q[i].y1, q[i].y2,
q[i].K, aux);
}
// Compute the readonly answer
updateMatrix(mat, aux);
// Print the updated matrix
printMatrix(mat);
}
// Driver Code
public static void Main(String[] args)
{
// Given Matrix
int [,]mat = { { 1, 0, 1, 2 },
{ 0, 2, 4, 1 },
{ 1, 2, 1, 0 } };
int Q = 1;
// Given Queries
query []q = {new query( 0, 0, 1, 1, 2 )};
// Function call
matrixQuery(mat, Q, q);
}
}
// This code is contributed by 29AjayKumar
Javascript
3 2 1 2
2 4 4 1
1 2 1 0
时间复杂度: O(Q + N*M)
辅助空间: O(N*M)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。