Open In App

Print the Array of size N containing values in range [0, M) after Q query updates

Given array arr[] of size N containing cyclic variables having states from 0 to (M – 1) (i.e when incremented from M-1 it goes to 0). The task is to fulfill the Q queries of which are of any of the following two types:

Examples:



Input: arr[] = {2, 2, 7, 2, 5}, Q = 5, M = 8
queries[][] = {{1, 0, 3, 4}, 
                     {1, 4, 4, 2}, 
                     {1, 0, 0, 7}, 
                     {2, 1, 3}, 
                     {2, 3, 3}}
Output: {6, 3, 6}, {6}
Explanation: The states after performing each operation are:
After 1st: {6, 6, 3, 6, 5}
After 2nd: {6, 6, 3, 6, 7}
After 3rd: {5, 6, 3, 6, 7}
So in 4th query elements from index 1 to 3 and in 5th query element in index 3 are printed.

Input: arr[] = [2, 3, 4, 5], Q = 3, M = 6
queries[][] = {{1, 0, 0, 3}, 
                     {1, 1, 2, 2}, 
                     {1, 3, 3, 1}, 
                     {2, 0, 3}}
Output: {5, 5, 1, 1}



 

Approach: The problem can be solved using greedy approach. Follow the steps mentioned below to implement the approach:

Below is the implementation of the above approach.




// C++ code to implement above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to implement the queries
void update(int arr[], int N, int M, int Q,
            vector<vector<int> >& queries)
{
    // Loop to implement the queries
    for (int i = 0; i < Q; i++) {
        if (queries[i][0] == 1) {
            for (int j = queries[i][1];
                 j <= queries[i][2];
                 j++)
                arr[j] = (arr[j] +
                          queries[i][3]) % M;
        }
        else if (queries[i][0] == 2) {
            for (int j = queries[i][1];
                 j <= queries[i][2];
                 j++)
                cout << arr[j] << " ";
            cout << endl;
        }
    }
}
 
// Driver's code
int main()
{
    int N = 5, M = 8, Q = 5;
    int arr[] = { 2, 2, 7, 2, 5 };
    vector<vector<int> > queries(Q);
    queries[0] = { 1, 0, 3, 4 };
    queries[1] = { 1, 4, 4, 2 };
    queries[2] = { 1, 0, 0, 7 };
    queries[3] = { 2, 1, 3 };
    queries[4] = { 2, 3, 3 };
 
    update(arr, N, M, Q, queries);
    return 0;
}




// Java code to implement the above approach
import java.io.*;
class GFG {
 
  // Function to implement the queries
  public static void update(int[] arr, int N, int M,
                            int Q, int[][] queries)
  {
 
    // Loop to implement the queries
    for (int i = 0; i < Q; i++) {
      if (queries[i][0] == 1) {
        for (int j = queries[i][1];
             j <= queries[i][2];
             j++)
          arr[j] = (arr[j] +
                    queries[i][3]) % M;
      }
      else if (queries[i][0] == 2) {
        for (int j = queries[i][1];
             j <= queries[i][2];
             j++)
          System.out.print(arr[j]+ " ");
        System.out.println();
      }
    }
  }
 
  // Driver's code
  public static void main (String[] args)
  {
    int N = 5, M = 8, Q = 5;
    int[] arr = { 2, 2, 7, 2, 5 };
    int[][] queries = new int[][]
    {
      new int[] { 1, 0, 3, 4 },
      new int[] { 1, 4, 4, 2 },
      new int[] { 1, 0, 0, 7 },
      new int[] { 2, 1, 3 },
      new int[] { 2, 3, 3 }
    };
    update(arr, N, M, Q, queries);
  }
}
 
// This code is contributed by Shubham Singh




# Python3 code to implement above approach
 
# Function to implement the queries
def update(arr, N, M,  Q, queries):
 
    # Loop to implement the queries
    for i in range(Q):
        if (queries[i][0] == 1):
            for j in range(queries[i][1],
                           queries[i][2] + 1):
 
                arr[j] = (arr[j] +
                          queries[i][3]) % M
 
        elif (queries[i][0] == 2):
            for j in range(queries[i][1],
                           queries[i][2] + 1):
 
                print(arr[j], end = " ")
                 
            print()
 
# Driver code
if __name__ == "__main__":
 
    N = 5
    M = 8
    Q = 5
    arr = [2, 2, 7, 2, 5]
    queries = []
     
    queries.append([1, 0, 3, 4])
    queries.append([1, 4, 4, 2])
    queries.append([1, 0, 0, 7])
    queries.append([2, 1, 3])
    queries.append([2, 3, 3])
 
    update(arr, N, M, Q, queries)
     
# This code is contributed by ukasp




// C# code to implement the above approach
using System;
public class GFG{
 
  // Function to implement the queries
  public static void update(int[] arr, int N, int M, int Q, int[][] queries)
  {
    // Loop to implement the queries
    for (int i = 0; i < Q; i++) {
      if (queries[i][0] == 1) {
        for (int j = queries[i][1];
             j <= queries[i][2];
             j++)
          arr[j] = (arr[j] +
                    queries[i][3]) % M;
      }
      else if (queries[i][0] == 2) {
        for (int j = queries[i][1];
             j <= queries[i][2];
             j++)
          Console.Write(arr[j]+ " ");
        Console.WriteLine();
      }
    }
  }
 
  // Driver's code
  public static void Main()
  {
    int N = 5, M = 8, Q = 5;
    int[] arr = { 2, 2, 7, 2, 5 };
    int[][] queries = new int[][]
    {
      new int[] { 1, 0, 3, 4 },
      new int[] { 1, 4, 4, 2 },
      new int[] { 1, 0, 0, 7 },
      new int[] { 2, 1, 3 },
      new int[] { 2, 3, 3 }
    };
    update(arr, N, M, Q, queries);
  }
}
 
// This code is contributed by Shubham Singh




<script>
       // JavaScript code for the above approach
 
       // Function to implement the queries
       function update(arr, N, M, Q,
           queries)
       {
           // Loop to implement the queries
           for (let i = 0; i < Q; i++) {
               if (queries[i][0] == 1) {
                   for (let j = queries[i][1];
                       j <= queries[i][2];
                       j++)
                       arr[j] = (arr[j] +
                           queries[i][3]) % M;
               }
               else if (queries[i][0] == 2) {
                   for (let j = queries[i][1];
                       j <= queries[i][2];
                       j++)
                       document.write(arr[j] + " ");
                   document.write('<br>')
               }
           }
       }
 
       // Driver's code
       let N = 5, M = 8, Q = 5;
       let arr = [2, 2, 7, 2, 5];
       let queries = new Array(Q);
       queries[0] = [1, 0, 3, 4];
       queries[1] = [1, 4, 4, 2];
       queries[2] = [1, 0, 0, 7];
       queries[3] = [2, 1, 3];
       queries[4] = [2, 3, 3];
 
       update(arr, N, M, Q, queries);
 
 // This code is contributed by Potta Lokesh
   </script>

Output
6 3 6 
6 


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

Another method of the greedy approach: To solve the problem, we can loop through each query and check its type. If the query is of the first type, we can loop through the range of elements and increment each element cyclically by the given amount. If the query is of the second type, we can loop through the range of elements and print each element.

Steps to implement the above approach:

Below is the implementation of the above approach:




#include <bits/stdc++.h>
using namespace std;
 
// Function to increment all values in the range [L, R]
// cyclically by K
void incrementRange(int arr[], int L, int R, int K, int M)
{
    for (int i = L; i <= R; i++) {
        arr[i] = (arr[i] + K)
                 % M; // add K to arr[i] and take modulo M
                      // to handle the cyclic nature
    }
}
 
// Function to print all values in the range [L, R]
void printRange(int arr[], int L, int R)
{
    for (int i = L; i <= R; i++) {
        cout << arr[i]
             << " "; // print the value at each index i in
                     // the range [L, R]
    }
    cout << endl;
}
 
// Function to implement the given queries
void update(int arr[], int N, int M, int Q,
            vector<vector<int> >& queries)
{
    for (int i = 0; i < Q;
         i++) { // loop through all the queries
        if (queries[i][0]
            == 1) { // if the query is of the first type
            incrementRange(
                arr, queries[i][1], queries[i][2],
                queries[i][3],
                M); // call the incrementRange function to
                    // update the range [L, R]
        }
        else if (queries[i][0] == 2) { // if the query is of
                                       // the second type
            printRange(
                arr, queries[i][1],
                queries[i]
                       [2]); // call the printRange function
                             // to print the range [L, R]
        }
    }
}
 
// Driver's code
int main()
{
    int N = 5, M = 8, Q = 5;
    int arr[] = { 2, 2, 7, 2, 5 };
    vector<vector<int> > queries(Q);
    queries[0] = { 1, 0, 3, 4 };
    queries[1] = { 1, 4, 4, 2 };
    queries[2] = { 1, 0, 0, 7 };
    queries[3] = { 2, 1, 3 };
    queries[4] = { 2, 3, 3 };
 
    update(arr, N, M, Q,
           queries); // call the update function to
                     // implement the queries
    return 0;
}




import java.util.*;
 
public class Main {
 
    // Function to increment all values in the range [L, R]
    // cyclically by K
    public static void incrementRange(int[] arr, int L,
                                      int R, int K, int M)
    {
        for (int i = L; i <= R; i++) {
            arr[i] = (arr[i] + K)
                     % M; // add K to arr[i] and take modulo
                          // M to handle the cyclic nature
        }
    }
 
    // Function to print all values in the range [L, R]
    public static void printRange(int[] arr, int L, int R)
    {
        for (int i = L; i <= R; i++) {
            System.out.print(
                arr[i]
                + " "); // print the value at each index i
                        // in the range [L, R]
        }
        System.out.println();
    }
 
    // Function to implement the given queries
    public static void update(int[] arr, int N, int M,
                              int Q,
                              List<List<Integer> > queries)
    {
        for (int i = 0; i < Q;
             i++) { // loop through all the queries
            if (queries.get(i).get(0)
                == 1) { // if the query is of the first type
                incrementRange(
                    arr, queries.get(i).get(1),
                    queries.get(i).get(2),
                    queries.get(i).get(3),
                    M); // call the incrementRange function
                        // to update the range [L, R]
            }
            else if (queries.get(i).get(0)
                     == 2) { // if the query is of
                             // the second type
                printRange(
                    arr, queries.get(i).get(1),
                    queries.get(i).get(
                        2)); // call the printRange function
                             // to print the range [L, R]
            }
        }
    }
 
    // Driver's code
    public static void main(String[] args)
    {
        int N = 5, M = 8, Q = 5;
        int[] arr = { 2, 2, 7, 2, 5 };
        List<List<Integer> > queries = new ArrayList<>();
        queries.add(Arrays.asList(1, 0, 3, 4));
        queries.add(Arrays.asList(1, 4, 4, 2));
        queries.add(Arrays.asList(1, 0, 0, 7));
        queries.add(Arrays.asList(2, 1, 3));
        queries.add(Arrays.asList(2, 3, 3));
 
        update(arr, N, M, Q,
               queries); // call the update function to
                         // implement the queries
    }
}




def incrementRange(arr, L, R, K, M):
    # Function to increment all values in the range [L, R]
    # cyclically by K
    for i in range(L, R+1):
        arr[i] = (arr[i] + K) % M
 
 
def printRange(arr, L, R):
    # Function to print all values in the range [L, R]
    for i in range(L, R+1):
        print(arr[i], end=" ")
    print()
 
 
def update(arr, N, M, Q, queries):
    # Function to implement the given queries
    for i in range(Q):
        if queries[i][0] == 1:
            # if the query is of the first type
            incrementRange(arr, queries[i][1], queries[i][2],
                           queries[i][3], M)
            # call the incrementRange function to update the range [L, R]
        elif queries[i][0] == 2:
            # if the query is of the second type
            printRange(arr, queries[i][1], queries[i][2])
            # call the printRange function to print the range [L, R]
 
 
N = 5
M = 8
Q = 5
arr = [2, 2, 7, 2, 5]
queries = [[1, 0, 3, 4], [1, 4, 4, 2], [1, 0, 0, 7], [2, 1, 3], [2, 3, 3]]
 
update(arr, N, M, Q,
       queries)  # call the update function to implement the queries




using System;
using System.Collections.Generic;
using System.Linq;
 
public class MainClass {
 
    // Function to increment all values
    // in the range [L, R] cyclically by K
    public static void IncrementRange(int[] arr, int L,
                                      int R, int K, int M)
    {
        for (int i = L; i <= R; i++) {
 
            // add K to arr[i] and take modulo
            // M to handle the cyclic nature
            arr[i] = (arr[i] + K) % M;
        }
    }
 
    // Function to print all values
    // in the range [L, R]
    public static void PrintRange(int[] arr, int L, int R)
    {
        for (int i = L; i <= R; i++) {
 
            // print the value at each index i
            // in the range [L, R]
            Console.Write(arr[i] + " ");
        }
        Console.WriteLine();
    }
 
    // Function to implement given queries
    public static void Update(int[] arr, int N, int M,
                              int Q,
                              List<List<int> > queries)
    {
        // loop through all the queries
        for (int i = 0; i < Q; i++) {
 
            // if the query is of the first type
            if (queries[i][0] == 1) {
 
                // call the IncrementRange function
                // to update the range [L, R]
                IncrementRange(arr, queries[i][1],
                               queries[i][2], queries[i][3],
                               M);
            }
 
            // if the query is of the
            // second type
            else if (queries[i][0] == 2) {
 
                // call the PrintRange
                // function to print the
                // range [L, R]
                PrintRange(arr, queries[i][1],
                           queries[i][2]);
            }
        }
    }
 
    // Driver's code
    public static void Main()
    {
        int N = 5, M = 8, Q = 5;
        int[] arr = { 2, 2, 7, 2, 5 };
        List<List<int> > queries = new List<List<int> >();
        queries.Add(new List<int>{ 1, 0, 3, 4 });
        queries.Add(new List<int>{ 1, 4, 4, 2 });
        queries.Add(new List<int>{ 1, 0, 0, 7 });
        queries.Add(new List<int>{ 2, 1, 3 });
        queries.Add(new List<int>{ 2, 3, 3 });
 
        Update(arr, N, M, Q, queries);
    }
}




// Function to increment all values in the range [L, R]
// cyclically by K
function incrementRange(arr, L, R, K, M) {
    for (let i = L; i <= R; i++) {
        arr[i] = (arr[i] + K) % M; // add K to arr[i] and take modulo M
                                   // to handle the cyclic nature
    }
}
 
// Function to print all values in the range [L, R]
function printRange(arr, L, R) {
    let output = "";
    for (let i = L; i <= R; i++) {
        output += arr[i] + " "; // concatenate the value at each index i in
                                // the range [L, R]
    }
    console.log(output);
}
 
// Function to implement the given queries
function update(arr, N, M, Q, queries) {
    for (let i = 0; i < Q; i++) { // loop through all the queries
        if (queries[i][0] === 1) { // if the query is of the first type
            incrementRange(arr, queries[i][1], queries[i][2], queries[i][3], M);
        } else if (queries[i][0] === 2) { // if the query is of the second type
            printRange(arr, queries[i][1], queries[i][2]);
        }
    }
}
 
// Driver's code
 
const N = 5, M = 8, Q = 5;
const arr = [2, 2, 7, 2, 5];
const queries = [
    [1, 0, 3, 4],
    [1, 4, 4, 2],
    [1, 0, 0, 7],
    [2, 1, 3],
    [2, 3, 3]
];
 
update(arr, N, M, Q, queries); // call the update function to
                               // implement the queries

Output
6 3 6 
6 

Time Complexity: O(Q * (R-L)), where Q is the number of queries, and R-L is the size of the range of indices to be updated or printed.
Auxiliary Space: O(N)


Article Tags :