Open In App

Grid Evolution and Query Evaluation

Last Updated : 20 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a grid of dimensions n rows and m columns, where each element initially contains an integer from 0 to k-1. The grid evolves over time, with each element undergoing the transformation (grid[i][j] + 1) % k after each unit of time. You are also provided with a series of queries, each defined by [t, val, lx, ly, rx, ry], the task is to determine, for each query, the number of elements in the given subgrid at time t that have the specified value val, where:

  • t represents the time,
  • val is the value to be checked,
  • lx, ly are the coordinates of the top-left corner of the subgrid, and
  • rx, ry are the coordinates of the bottom-right corner of the subgrid.

Note: The grid starts at time t=0 and the indices are 0-based. K values vary from 0 to 5

Examples:

Input: n = 2, m = 2, k = 3, grid = {{0, 1}, {2, 2}}, q = 1, queries = {{1, 0, 0, 0, 1, 1}}
Output: {2}
Explanation: The given query can be interpreted as

  • t (time) = 1
  • val (value) = 0
  • lx, ly (coordinates of the top left corner of subgrid) = (0,0)
  • rx, ry (coordinates of the bottom right corner of subgrid) = (1,1)

The count of 0s at time = 1 in the given subgrid is 2.

Input: n = 3, m = 3, k = 4, grid = {{0, 1, 1}, {1, 2, 3}, {0, 2, 1}}, q = 2, queries = {{0, 1, 0, 0, 2, 2}, {2, 2, 1, 1, 2, 2}}
Output: {4, 0}
Explanation:

  • For query 1, count of val=1 is 4.
  • For query 2, count of val=2 is 0.

Approach: This can be solved with the following idea:

As k value can be between 0 and 5, it’s optimal to create a vector which will be storing count of each number at each cordinate. To answer queires we can calculate frequency of each number.

Below are the steps involved:

  • Create a 2D vector having value assigned a vector of size 6.
  • For each coordinate assign how many times each element has occured.
    • Iterate for 6 elements each element occuring will be counted by top + left – diagonal(if under coordinates).
  • For each query, see top left and bottom right, calculate freuency from vector intialized above.
  • In vector ans, add how many elements are having value equal to val after t time and % k.
  • Return ans.

Below is the implementation of the code:

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
 
// Function to find number of times a particular
// element ocurring in a submatrix
vector<int> k_Transformation(int n, int m, int k,
                             vector<vector<int> > grid,
                             int q,
                             vector<vector<int> > queries)
{
 
    // Declare a 2D vector storing count of 6 elements
    vector<vector<vector<int> > > pre(
        n + 1,
        vector<vector<int> >(m + 1, vector<int>(6, 0)));
 
    // Iterate in grid
    for (int i = 0; i < n; i++) {
 
        for (int j = 0; j < m; j++) {
 
            // Increment the frequency of
            // elemnent occuring
            pre[i][j][grid[i][j]]++;
 
            // Iterate for those 6 elements
            for (int k = 0; k <= 5; k++) {
 
                // Store frequency of each
                // element upto this coordinate
                if (i - 1 >= 0)
                    pre[i][j][k] += pre[i - 1][j][k];
 
                if (j - 1 >= 0)
                    pre[i][j][k] += pre[i][j - 1][k];
                if (i - 1 >= 0 && j - 1 >= 0)
                    pre[i][j][k] -= pre[i - 1][j - 1][k];
            }
        }
    }
 
    // Initialise a vector to store ans
    vector<int> ans;
 
    // Iterate in queries
    for (auto i : queries) {
 
        int t = i[0];
        int val = i[1];
        int l1 = i[2];
        int r1 = i[3];
        int l2 = i[4];
        int r2 = i[5];
 
        // Calculating for particular that
        // submatrix mentioned
        vector<int> cnt(6, 0);
 
        for (int j = 0; j <= 5; j++) {
            cnt[j] += pre[l2][r2][j];
            if (l1 - 1 >= 0) {
                cnt[j] -= pre[l1 - 1][r2][j];
            }
            if (r1 - 1 >= 0) {
                cnt[j] -= pre[l2][r1 - 1][j];
            }
            if (l1 - 1 >= 0 && r1 - 1 >= 0) {
                cnt[j] += pre[l1 - 1][r1 - 1][j];
            }
        }
 
        // Check how many elements have value
        // equal to val by doing mod k
        int c = 0;
 
        for (int j = 0; j <= 5; j++) {
            if (((j + t) % k) == val) {
                c += cnt[j];
            }
        }
        ans.push_back(c);
    }
 
    // Return the vector ans
    return ans;
}
 
// Driver code
int main()
{
 
    int n = 2;
    int m = 2;
    int k = 3;
    vector<vector<int> > grid = { { 0, 1 }, { 2, 2 } };
    int q = 1;
    vector<vector<int> > queries = { { 1, 0, 0, 0, 1, 1 } };
 
    vector<int> ans
        = k_Transformation(n, m, k, grid, q, queries);
 
    for (auto a : ans) {
        cout << a << " ";
    }
    return 0;
}


Java




import java.util.ArrayList;
import java.util.List;
 
public class Main {
 
    // Function to find number of times a particular
    // element occurring in a submatrix
    static List<Integer> kTransformation(int n, int m, int k,
            List<List<Integer>> grid, int q, List<List<Integer>> queries) {
 
        // Declare a 3D list storing count of 6 elements
        List<List<List<Integer>>> pre = new ArrayList<>();
        for (int i = 0; i <= n; i++) {
            List<List<Integer>> temp1 = new ArrayList<>();
            for (int j = 0; j <= m; j++) {
                List<Integer> temp2 = new ArrayList<>();
                for (int l = 0; l < 6; l++) {
                    temp2.add(0);
                }
                temp1.add(temp2);
            }
            pre.add(temp1);
        }
 
        // Iterate in grid
        for (int i = 0; i < n; i++) {
 
            for (int j = 0; j < m; j++) {
 
                // Increment the frequency of
                // element occurring
                pre.get(i).get(j).set(grid.get(i).get(j),
                    pre.get(i).get(j).get(grid.get(i).get(j)) + 1);
 
                // Iterate for those 6 elements
                for (int k1 = 0; k1 <= 5; k1++) {
 
                    // Store frequency of each
                    // element up to this coordinate
                    if (i - 1 >= 0)
                        pre.get(i).get(j).set(k1,
                            pre.get(i).get(j).get(k1) + pre.get(i - 1).get(j).get(k1));
 
                    if (j - 1 >= 0)
                        pre.get(i).get(j).set(k1,
                            pre.get(i).get(j).get(k1) + pre.get(i).get(j - 1).get(k1));
 
                    if (i - 1 >= 0 && j - 1 >= 0)
                        pre.get(i).get(j).set(k1,
                            pre.get(i).get(j).get(k1) - pre.get(i - 1).get(j - 1).get(k1));
                }
            }
        }
 
        // Initialise a list to store ans
        List<Integer> ans = new ArrayList<>();
 
        // Iterate in queries
        for (List<Integer> i : queries) {
 
            int t = i.get(0);
            int val = i.get(1);
            int l1 = i.get(2);
            int r1 = i.get(3);
            int l2 = i.get(4);
            int r2 = i.get(5);
 
            // Calculating for particular that
            // submatrix mentioned
            List<Integer> cnt = new ArrayList<>();
            for (int j = 0; j <= 5; j++) {
                cnt.add(pre.get(l2).get(r2).get(j));
                if (l1 - 1 >= 0) {
                    cnt.set(j, cnt.get(j) - pre.get(l1 - 1).get(r2).get(j));
                }
                if (r1 - 1 >= 0) {
                    cnt.set(j, cnt.get(j) - pre.get(l2).get(r1 - 1).get(j));
                }
                if (l1 - 1 >= 0 && r1 - 1 >= 0) {
                    cnt.set(j, cnt.get(j) + pre.get(l1 - 1).get(r1 - 1).get(j));
                }
            }
 
            // Check how many elements have value
            // equal to val by doing mod k
            int c = 0;
 
            for (int j = 0; j <= 5; j++) {
                if (((j + t) % k) == val) {
                    c += cnt.get(j);
                }
            }
            ans.add(c);
        }
 
        // Return the list ans
        return ans;
    }
 
    // Driver code
    public static void main(String[] args) {
 
        int n = 2;
        int m = 2;
        int k = 3;
        List<List<Integer>> grid = List.of(List.of(0, 1), List.of(2, 2));
        int q = 1;
        List<List<Integer>> queries = List.of(List.of(1, 0, 0, 0, 1, 1));
 
        List<Integer> ans = kTransformation(n, m, k, grid, q, queries);
 
        for (int a : ans) {
            System.out.print(a + " ");
        }
    }
}
 
// This code is contributed by shivamgupta0987654321


Python3




# Python Implementation
def k_transformation(n, m, k, grid, q, queries):
    # Declare a 3D list storing count of 6 elements
    pre = [[[0 for _ in range(6)] for _ in range(m+1)] for _ in range(n+1)]
 
    # Iterate in grid
    for i in range(n):
        for j in range(m):
            # Increment the frequency of element occurring
            pre[i][j][grid[i][j]] += 1
 
            # Iterate for those 6 elements
            for k1 in range(6):
                # Store frequency of each element up to this coordinate
                if i - 1 >= 0:
                    pre[i][j][k1] += pre[i-1][j][k1]
                if j - 1 >= 0:
                    pre[i][j][k1] += pre[i][j-1][k1]
                if i - 1 >= 0 and j - 1 >= 0:
                    pre[i][j][k1] -= pre[i-1][j-1][k1]
 
    # Initialise a list to store ans
    ans = []
 
    # Iterate in queries
    for i in queries:
        t = i[0]
        val = i[1]
        l1 = i[2]
        r1 = i[3]
        l2 = i[4]
        r2 = i[5]
 
        # Calculating for particular that submatrix mentioned
        cnt = [pre[l2][r2][j] for j in range(6)]
        if l1 - 1 >= 0:
            cnt = [cnt[j] - pre[l1-1][r2][j] for j in range(6)]
        if r1 - 1 >= 0:
            cnt = [cnt[j] - pre[l2][r1-1][j] for j in range(6)]
        if l1 - 1 >= 0 and r1 - 1 >= 0:
            cnt = [cnt[j] + pre[l1-1][r1-1][j] for j in range(6)]
 
        # Check how many elements have value equal to val by doing mod k
        c = sum([cnt[j] for j in range(6) if (j + t) % k == val])
        ans.append(c)
 
    # Return the list ans
    return ans
 
# Driver code
n = 2
m = 2
k = 3
grid = [[0, 1], [2, 2]]
q = 1
queries = [[1, 0, 0, 0, 1, 1]]
 
ans = k_transformation(n, m, k, grid, q, queries)
 
for a in ans:
    print(a, end=" ")
# This code is contributed by Sakshi


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
    // Function to find the number of times a particular
    // element occurs in a submatrix
    static List<int>
    K_Transformation(int n, int m, int k,
                     List<List<int> > grid, int q,
                     List<List<int> > queries)
    {
        // Declare a 3D list storing count of 6 elements
        List<List<List<int> > > pre
            = new List<List<List<int> > >();
 
        for (int i = 0; i <= n; i++) {
            pre.Add(new List<List<int> >());
            for (int j = 0; j <= m; j++) {
                pre[i].Add(new List<int>(new int[6]));
            }
        }
 
        // Iterate in grid
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                // Increment the frequency of the element
                // occurring
                pre[i][j][grid[i][j]]++;
 
                // Iterate for those 6 elements
                for (int l = 0; l <= 5; l++) {
                    // Store frequency of each element up to
                    // this coordinate
                    if (i - 1 >= 0)
                        pre[i][j][l] += pre[i - 1][j][l];
 
                    if (j - 1 >= 0)
                        pre[i][j][l] += pre[i][j - 1][l];
                    if (i - 1 >= 0 && j - 1 >= 0)
                        pre[i][j][l]
                            -= pre[i - 1][j - 1][l];
                }
            }
        }
 
        // Initialise a list to store ans
        List<int> ans = new List<int>();
 
        // Iterate in queries
        foreach(var i in queries)
        {
            int t = i[0];
            int val = i[1];
            int l1 = i[2];
            int r1 = i[3];
            int l2 = i[4];
            int r2 = i[5];
 
            // Calculating for a particular submatrix
            // mentioned
            List<int> cnt = new List<int>(new int[6]);
 
            for (int j = 0; j <= 5; j++) {
                cnt[j] += pre[l2][r2][j];
                if (l1 - 1 >= 0) {
                    cnt[j] -= pre[l1 - 1][r2][j];
                }
                if (r1 - 1 >= 0) {
                    cnt[j] -= pre[l2][r1 - 1][j];
                }
                if (l1 - 1 >= 0 && r1 - 1 >= 0) {
                    cnt[j] += pre[l1 - 1][r1 - 1][j];
                }
            }
 
            // Check how many elements have value
            // equal to val by doing mod k
            int c = 0;
 
            for (int j = 0; j <= 5; j++) {
                if (((j + t) % k) == val) {
                    c += cnt[j];
                }
            }
            ans.Add(c);
        }
 
        // Return the list ans
        return ans;
    }
 
    // Driver code
    static void Main()
    {
        int n = 2;
        int m = 2;
        int k = 3;
        List<List<int> > grid
            = new List<List<int> >{ new List<int>{ 0, 1 },
                                    new List<int>{ 2, 2 } };
        int q = 1;
        List<List<int> > queries = new List<List<int> >{
            new List<int>{ 1, 0, 0, 0, 1, 1 }
        };
 
        List<int> ans
            = K_Transformation(n, m, k, grid, q, queries);
 
        foreach(var a in ans) { Console.Write(a + " "); }
    }
}
 
// This code is contributed by Susobhan Akhuli


Javascript




// Javascript program for the above approach
 
// Function to find number of times a particular
// element occurring in a submatrix
function kTransformation(n, m, k, grid, q, queries) {
 
    // Declare a 3D array storing count of 6 elements
    let pre = new Array(n + 1).fill(0).map(() =>
        new Array(m + 1).fill(0).map(() => new Array(6).fill(0))
    );
 
    // Iterate in grid
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
 
            // Increment the frequency of
            // element occurring
            pre[i][j][grid[i][j]]++;
 
            // Iterate for those 6 elements
            for (let k1 = 0; k1 <= 5; k1++) {
 
                // Store frequency of each
                // element up to this coordinate
                if (i - 1 >= 0)
                    pre[i][j][k1] += pre[i - 1][j][k1];
 
                if (j - 1 >= 0)
                    pre[i][j][k1] += pre[i][j - 1][k1];
 
                if (i - 1 >= 0 && j - 1 >= 0)
                    pre[i][j][k1] -= pre[i - 1][j - 1][k1];
            }
        }
    }
 
    // Initialise an array to store ans
    let ans = [];
 
    // Iterate in queries
    for (let i of queries) {
 
        let t = i[0];
        let val = i[1];
        let l1 = i[2];
        let r1 = i[3];
        let l2 = i[4];
        let r2 = i[5];
 
        // Calculating for a particular submatrix mentioned
        let cnt = new Array(6).fill(0);
        for (let j = 0; j <= 5; j++) {
            cnt[j] = pre[l2][r2][j];
            if (l1 - 1 >= 0) {
                cnt[j] -= pre[l1 - 1][r2][j];
            }
            if (r1 - 1 >= 0) {
                cnt[j] -= pre[l2][r1 - 1][j];
            }
            if (l1 - 1 >= 0 && r1 - 1 >= 0) {
                cnt[j] += pre[l1 - 1][r1 - 1][j];
            }
        }
 
        // Check how many elements have value
        // equal to val by doing mod k
        let c = 0;
 
        for (let j = 0; j <= 5; j++) {
            if (((j + t) % k) === val) {
                c += cnt[j];
            }
        }
        ans.push(c);
    }
 
    // Return the array ans
    return ans;
}
 
// Driver code
let n = 2;
let m = 2;
let k = 3;
let grid = [[0, 1], [2, 2]];
let q = 1;
let queries = [[1, 0, 0, 0, 1, 1]];
 
let ans = kTransformation(n, m, k, grid, q, queries);
 
console.log(ans.join(' '));
 
// This code is contributed by Susobhan Akhuli


Output

2 








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



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads