Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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:

  • 1st Type: 1 L R K – increment all the values in range of indices [L, R], K times cyclically.
  • 2nd Type: 2 L R – print the updated values in range of indices [L, R].

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:

  • When a query is of first type update all the values in range [L, R], K times.
  • When a query is of second type then print the value in range [L, R].

Below is the implementation of the above approach.

C++14




// 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




// 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




# 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#




// 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


Javascript




<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:

  • Initialize the input array arr[] of size N containing cyclic variables having states from 0 to (M – 1).
  • Initialize a vector queries of size Q, which contains Q queries of two types.
  • Loop through each query in the queries vector:
    • If the query is of the first type (1 L R K), then loop through the range of indices [L, R] and increment each element in arr[] cyclically by K.
    •  If the query is of the second type (2 L R), then loop through the range of indices [L, R] and print each element in arr[].
  • End of loop.
  • Print the updated values in arr[].

Below is the implementation of the above approach:

C++




#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;
}


Java




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
    }
}


Python3




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


C#




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);
    }
}


Javascript




// 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)



Last Updated : 13 Sep, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads