# Find the sum of diagonals passing through given coordinates for Q query

Given a 2D matrix of size N x M and Q queries where each query represents a coordinate (x, y) of the matrix, the task is to find the sum of all elements lying in the diagonals that pass through the given point.

Examples:

Input: N = 4, M = 4, mat[][] = {{1, 2, 2, 1}, {2, 4, 2, 4}, {2, 2, 3, 1}, {2, 4, 2, 4}}, query = { {0, 0}, {3, 1}, {3, 3} }
Output:  12, 13, 12
Explanation:
For query 1, The sum of all diagonal elements from (0, 0) is 1 + 4 + 3 + 4 = 12
For query 2, The sum of all diagonal elements from (3, 1) is 2 + 4 + 3 + 4 = 13
For query 3, The sum of all diagonal elements from (3, 3) is 4 + 3 + 4 + 1 = 12

Input: N = 3, M = 4, mat[][] = {{1, 0, 1}, {0, 1, 1}, {1, 1, 0}}, query = {{1, 1}, {2, 1}}
Output: 4, 2

Naive approach: The simple way to solve the problem is as follows:

• For each query run a loop to calculate the sum of the left inclined diagonal that passes through (x, y).
• Run another loop to calculate the sum of the right inclined diagonal that passes (x, y).
• In the calculation of these two side diagonals, we counted (x, y) twice. So now subtract that from the summation of both diagonal sums.

Time Complexity: O(Q * N * M)
Auxiliary Space: O(1)

Efficient Approach: The problem can be solved efficiently based on the following idea:

Pre-compute the left inclined and right inclined diagonal sums and store it in such a way that can be easily accessed and utilized for all values of (x, y)

In any matrix of size N x M, the total number of left inclined diagonal or right inclined diagonal is always N + M – 1. So create two vectors of size (N + M – 1) to store the sum of every that particular type of diagonal in the respective vector.

The value of (i+j) along right inclined diagonals are equals and (N-i+j-1) along left inclined diagonals are equal. So these values can be used as the indices for storing the sum of that diagonal.

Illustrations:

In this 3 x 4 matrix:

1     2     3     4
________________

1  | A00  A01  A02  A03

2  | A10  A11  A12  A13

3  | A20  A21  A22  A23

• For (1, 1) The output will be (A00 + A11 + A22 + A20 + A02).
• For (2, 1) The output will be (A10 + A21 + A12 + A03)
• For right inclined diagonals
• Start from top left and keep covering all diagonals till bottom right.
• According to above illustration the ith right inclined diagonal contains following elements
• 0th diagonal = A00
• 1st diagonal  = A10+ A01
• 2nd diagonal = A20 + A11 + A02
• 3rd diagonal = A21 + A12 + A03
• 4th diagonal = A22 + A13
• 5th diagonal = A23
• Storing the above values in the vector right_inclined_digsum in the same order.
• In order to check the (x, y) element belonging to which diagonal just observe that Aij belongs to (i + j)th right inclined diagonal.
• For left inclined diagonals
• Start from bottom left and keep covering all diagonals till top right
• According to above illustration the ith left inclined diagonal contains following elements
• 0th diagonal = A20
• 1st diagonal = A10 + A21
• 2nd diagonal = A00 + A11 + A22
• 3rd diagonal = A01 + A12 + A23
• 4th diagonal = A02 + A13
• 5th diagonal = A03
• Storing the above values in the vector left_inclined_digsum in the same order.
• In order to check the (x, y) element belongs to which diagonal just observe that Aij belongs to (N – i + j – 1)th left inclined diagonal.
• After precomputing all these data, for each query of (x, y) output
•  right_inclined_digsum[x + y] + left_inclined_digsum[N – x + y – 1] – arr[x][y]

Follow the steps mentioned below to implement the idea:

• Create two vectors to store the diagonal sums (one for left inclined and the other for right inclined).
• Store the sum of the diagonals in the indices as shown above.
• Find the diagonals of which the current coordinate is a part.
• Calculate the sum as shown above.

Below is the implementation of the above approach.

## C++

 `// C++ code for the above approach:`   `#include ` `using` `namespace` `std;` `const` `int` `n = 4;` `const` `int` `m = 4;`   `// Function for diagonal sum` `int` `diagonal_sum(vector >& arr,` `                 ``vector<``int``>& right_inclined_digsum,` `                 ``vector<``int``>& left_inclined_digsum, ``int` `n,` `                 ``int` `x, ``int` `y)` `{` `    ``// To make it compatible with 0 based indexing` `    ``int` `a = (n - x) + y - 1;` `    ``int` `b = x + y;` `    ``int` `sum = right_inclined_digsum[b]` `              ``+ left_inclined_digsum[a] - arr[x][y];` `    ``return` `sum;` `}`   `// Precomputaion` `void` `precompute(``int` `n, ``int` `m, vector > arr,` `                ``vector<``int``>& right_inclined_digsum,` `                ``vector<``int``>& left_inclined_digsum)` `{`   `    ``// To cover all diagonals of (/) type` `    ``for` `(``int` `i = 0; i < n; i++) {` `        ``for` `(``int` `j = 0; j < m; j++) {` `            ``right_inclined_digsum[i + j] += arr[i][j];` `        ``}` `    ``}`   `    ``// To cover all diagonals of (\) type` `    ``for` `(``int` `i = n - 1; i >= 0; i--) {` `        ``for` `(``int` `j = 0; j < m; j++) {` `            ``left_inclined_digsum[n - 1 - i + j]` `                ``+= arr[i][j];` `        ``}`   `        ``// precomputaion done` `    ``}` `}`   `void` `solve(vector >& arr, ``int` `Q,` `           ``vector >& query)` `{` `    ``vector<``int``> right_inclined_digsum(n + m - 1, 0);` `    ``vector<``int``> left_inclined_digsum(n + m - 1, 0);`   `    ``// Function for precomputation` `    ``precompute(n, m, arr, right_inclined_digsum,` `               ``left_inclined_digsum);`   `    ``// Iterator for these coordinates` `    ``int` `it = 0;`   `    ``while` `(Q--) {` `        ``int` `x = query[it].first;` `        ``int` `y = query[it].second;` `        ``cout << diagonal_sum(arr, right_inclined_digsum,` `                             ``left_inclined_digsum, n, x, y)` `             ``<< ``"\n"``;` `        ``it++;` `    ``}` `}` `// Drivers code` `int` `main()` `{` `    ``vector > arr = { { 1, 2, 2, 1 },` `                                 ``{ 2, 4, 2, 4 },` `                                 ``{ 2, 2, 3, 1 },` `                                 ``{ 2, 4, 2, 4 } };` `    ``int` `Q = 3;`   `    ``// Defining coordinates for each query` `    ``vector > query;` `    ``query.push_back({ 0, 0 });` `    ``query.push_back({ 3, 1 });` `    ``query.push_back({ 3, 3 });`   `    ``// Function call` `    ``solve(arr, Q, query);` `    ``return` `0;` `}`

## Java

 `// Java code to implement the approach` `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG {` `    ``static` `int` `n = ``4``;` `    ``static` `int` `m = ``4``;`   `    ``// Function for diagonal sum` `    ``static` `int` `diagonal_sum(``int``[][] arr,` `                            ``int``[] right_inclined_digsum,` `                            ``int``[] left_inclined_digsum,` `                            ``int` `n, ``int` `x, ``int` `y)` `    ``{` `        ``// To make it compatible with 0 based indexing` `        ``int` `a = (n - x) + y - ``1``;` `        ``int` `b = x + y;` `        ``int` `sum = right_inclined_digsum[b]` `                  ``+ left_inclined_digsum[a] - arr[x][y];` `        ``return` `sum;` `    ``}`   `    ``// Precomputaion` `    ``static` `void` `precompute(``int` `n, ``int` `m, ``int``[][] arr,` `                           ``int``[] right_inclined_digsum,` `                           ``int``[] left_inclined_digsum)` `    ``{`   `        ``// To cover all diagonals of (/) type` `        ``for` `(``int` `i = ``0``; i < n; i++) {` `            ``for` `(``int` `j = ``0``; j < m; j++) {` `                ``right_inclined_digsum[i + j] += arr[i][j];` `            ``}` `        ``}`   `        ``// To cover all diagonals of (\) type` `        ``for` `(``int` `i = n - ``1``; i >= ``0``; i--) {` `            ``for` `(``int` `j = ``0``; j < m; j++) {` `                ``left_inclined_digsum[n - ``1` `- i + j]` `                    ``+= arr[i][j];` `            ``}` `            ``// precomputaion done` `        ``}` `    ``}`   `    ``static` `void` `solve(``int``[][] arr, ``int` `Q, ``int``[][] query)` `    ``{` `        ``int``[] right_inclined_digsum = ``new` `int``[n + m - ``1``];` `        ``int``[] left_inclined_digsum = ``new` `int``[n + m - ``1``];`   `        ``// Function for precomputation` `        ``precompute(n, m, arr, right_inclined_digsum,` `                   ``left_inclined_digsum);`   `        ``// Iterator for these coordinates` `        ``int` `it = ``0``;`   `        ``while` `(Q-- > ``0``) {` `            ``int` `x = query[it][``0``];` `            ``int` `y = query[it][``1``];` `            ``System.out.println(diagonal_sum(` `                ``arr, right_inclined_digsum,` `                ``left_inclined_digsum, n, x, y));` `            ``it++;` `        ``}` `    ``}` `    ``// Driver code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int``[][] arr = { { ``1``, ``2``, ``2``, ``1` `},` `                        ``{ ``2``, ``4``, ``2``, ``4` `},` `                        ``{ ``2``, ``2``, ``3``, ``1` `},` `                        ``{ ``2``, ``4``, ``2``, ``4` `} };` `        ``int` `Q = ``3``;`   `        ``// Defining coordinates for each query` `        ``int``[][] query = ``new` `int``[``3``][``2``];` `        ``query[``0``] = ``new` `int``[] { ``0``, ``0` `};` `        ``query[``1``] = ``new` `int``[] { ``3``, ``1` `};` `        ``query[``2``] = ``new` `int``[] { ``3``, ``3` `};`   `        ``// Function call` `        ``solve(arr, Q, query);` `    ``}` `}` `// This code is contributed by Karandeep1234`

## Python3

 `# Python code for the above approach`     `n ``=` `4` `m ``=` `4` `right_inclined_digsum ``=` `[``0``]``*``(n``+``m``-``1``)` `left_inclined_digsum ``=` `[``0``]``*``(n``+``m``-``1``)` `# Function for diagonal sum`     `def` `diagonal_sum(arr, right_inclined_digsum, left_inclined_digsum, n, x, y):` `    ``# To make it compatible with 0 based indexing` `    ``a ``=` `(n``-``x)``+``y``-``1` `    ``b ``=` `x``+``y` `    ``summ ``=` `right_inclined_digsum[b]``+``left_inclined_digsum[a]``-``arr[x][y]` `    ``return` `summ` `# Precomputaion function`     `def` `precompute(n, m, arr, right_inclined_digsum, left_inclined_digsum):` `    ``# To cover all diagonals of (/) type` `    ``for` `i ``in` `range``(n):` `        ``for` `j ``in` `range``(m):` `            ``right_inclined_digsum[i``+``j] ``+``=` `arr[i][j]` `    ``# To cover all diagonals of (\) type` `    ``for` `i ``in` `range``(n``-``1``, ``-``1``, ``-``1``):` `        ``for` `j ``in` `range``(``0``, m):` `            ``left_inclined_digsum[n``-``1``-``i``+``j] ``+``=` `arr[i][j]` `    ``# precomputaion done`     `def` `solve(arr, Q, query):` `    ``# Function for precomputation` `    ``precompute(n, m, arr, right_inclined_digsum, left_inclined_digsum)` `    ``# Iterator for these coordinates` `    ``it ``=` `0` `    ``while``(Q > ``0``):` `        ``x ``=` `query[it][``0``]` `        ``y ``=` `query[it][``1``]` `        ``print``(diagonal_sum(arr, right_inclined_digsum,` `                           ``left_inclined_digsum, n, x, y))` `        ``it ``+``=` `1` `        ``Q ``-``=` `1`     `# Drivers code` `if` `__name__ ``=``=` `"__main__"``:` `    ``arr ``=` `[[``1``, ``2``, ``2``, ``1``], [``2``, ``4``, ``2``, ``4``], [``2``, ``2``, ``3``, ``1``], [``2``, ``4``, ``2``, ``4``]]` `    ``Q ``=` `3` `    ``# Defining coordinates for each query` `    ``query ``=` `[]` `    ``query.append([``0``, ``0``])` `    ``query.append([``3``, ``1``])` `    ``query.append([``3``, ``3``])` `    ``# Function call` `    ``solve(arr, Q, query)` `" Code is written by RAJAT KUMAR [GLAU] "`

## C#

 `// C# code for the above approach:`   `using` `System;` `using` `System.Collections.Generic;`   `class` `pair {` `    ``public` `int` `first, second;` `    ``public` `pair(``int` `x, ``int` `y)` `    ``{` `        ``this``.first = x;` `        ``this``.second = y;` `    ``}` `}`   `class` `GFG {` `    ``static` `int` `n = 4;` `    ``static` `int` `m = 4;`   `    ``// Function for diagonal sum` `    ``static` `int` `diagonal_sum(``int``[, ] arr,` `                            ``List<``int``> right_inclined_digsum,` `                            ``List<``int``> left_inclined_digsum,` `                            ``int` `n, ``int` `x, ``int` `y)` `    ``{` `        ``// To make it compatible with 0 based indexing` `        ``int` `a = (n - x) + y - 1;` `        ``int` `b = x + y;` `        ``int` `sum = right_inclined_digsum[b]` `                  ``+ left_inclined_digsum[a] - arr[x, y];` `        ``return` `sum;` `    ``}`   `    ``// Precomputaion` `    ``static` `void` `precompute(``int` `n, ``int` `m, ``int``[, ] arr,` `                           ``List<``int``> right_inclined_digsum,` `                           ``List<``int``> left_inclined_digsum)` `    ``{`   `        ``// To cover all diagonals of (/) type` `        ``for` `(``int` `i = 0; i < n; i++) {` `            ``for` `(``int` `j = 0; j < m; j++) {` `                ``right_inclined_digsum[i + j] += arr[i, j];` `            ``}` `        ``}`   `        ``// To cover all diagonals of (\) type` `        ``for` `(``int` `i = n - 1; i >= 0; i--) {` `            ``for` `(``int` `j = 0; j < m; j++) {` `                ``left_inclined_digsum[n - 1 - i + j]` `                    ``+= arr[i, j];` `            ``}`   `            ``// precomputaion done` `        ``}` `    ``}`   `    ``static` `void` `solve(``int``[, ] arr, ``int` `Q, List query)` `    ``{` `        ``List<``int``> right_inclined_digsum = ``new` `List<``int``>();` `        ``List<``int``> left_inclined_digsum = ``new` `List<``int``>();`   `        ``for` `(``int` `i = 0; i < n + m - 1; i++) {` `            ``right_inclined_digsum.Add(0);` `            ``left_inclined_digsum.Add(0);` `        ``}`   `        ``// Function for precomputation` `        ``precompute(n, m, arr, right_inclined_digsum,` `                   ``left_inclined_digsum);`   `        ``// Iterator for these coordinates` `        ``int` `it = 0;`   `        ``while` `(Q > 0) {` `            ``Q--;` `            ``int` `x = query[it].first;` `            ``int` `y = query[it].second;` `            ``Console.WriteLine(diagonal_sum(` `                ``arr, right_inclined_digsum,` `                ``left_inclined_digsum, n, x, y));` `            ``it++;` `        ``}` `    ``}` `    ``// Drivers code` `    ``public` `static` `void` `Main(``string``[] args)` `    ``{` `        ``int``[, ] arr = { { 1, 2, 2, 1 },` `                        ``{ 2, 4, 2, 4 },` `                        ``{ 2, 2, 3, 1 },` `                        ``{ 2, 4, 2, 4 } };` `        ``int` `Q = 3;`   `        ``// Defining coordinates for each query` `        ``List query = ``new` `List();` `        ``query.Add(``new` `pair(0, 0));` `        ``query.Add(``new` `pair(3, 1));` `        ``query.Add(``new` `pair(3, 3));`   `        ``// Function call` `        ``solve(arr, Q, query);` `    ``}` `}`   `// This code is contributed by phasing17`

## Javascript

 ``

Output

```12
13
12```

Time Complexity: O(Q + N * M)
Auxiliary Space: O(N + M)

Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!

Previous
Next