Array range queries over range queries - GeeksforGeeks

28 Apr, 2022
Given an array of size n and a give set of commands of size m. The commands are enumerated from 1 to m. These commands can be of the following two types of commands: 
Type 1 [l r (1 <= l <= r <= n)] : Increase all elements of the array by one, whose indices belongs to the range [l, r]. In these queries of the index is inclusive in the range.Type 2 [l r (1 <= l <= r <= m)] : Execute all the commands whose indices are in the range [l, r]. In these queries of the index is inclusive in the range. It’s guaranteed that r is strictly less than the enumeration/number of the current command.
Type 1 [l r (1 <= l <= r <= n)] : Increase all elements of the array by one, whose indices belongs to the range [l, r]. In these queries of the index is inclusive in the range.
Type 2 [l r (1 <= l <= r <= m)] : Execute all the commands whose indices are in the range [l, r]. In these queries of the index is inclusive in the range. It’s guaranteed that r is strictly less than the enumeration/number of the current command.
Note : The array indexing is from 1 as per the problem statement.
Example 1 
Input : 5 5
        1 1 2
        1 4 5
        2 1 2
        2 1 3
        2 3 4
Output : 7 7 0 7 7
Explanation of Example 1 : Our array initially is of size 5 whose each element has been initialized to 0. So now the question states that we have 5 queries for the above example. 
Query 1 is of type 1 : As stated above we will simply increment the array indices by 1 the given indices are 1 and 2 so after the execution of the first our array turns down to be 1 1 0 0 0 .Query 2 is of type 1 : As stated above we will simply increment the array indices by 1 the given indices are 4 and 5 so after the execution of the first our array turns down to be 1 1 0 1 1 .Query 3 is of type 2 : As stated in the definition of this type of query we will execute the queries stated in the range i.e. we will operate the queries instead of the array. The range given is 1 and 2 so we will execute queries 1 and 2 again i.e. we will use repetitive approach for the type 2 queries so we will execute query 1 again and our array will be 2 2 0 1 1. Now when we execute the query we will execute query 2 and our resultant array will be 2 2 0 2 2 .Query 4 is of type 2 : As stated in the definition of this type of query we will execute the queries stated in the range i.e. we will operate the queries instead of the array. The range given is 1 and 3 so we will execute queries 1, 2 and 3 again i.e. using repetitive approach queries 1, 2 and 3 will be executed. After the execution of the query 1 again the array will be 3 3 0 2 2 . After the execution of the query 2 again the array will be 3 3 0 3 3 . Now due to query 3 inclusive in the range we will execute query 3 the resultant array will be 4 4 0 4 4 . As explained above.Query 5 is of type 2 : The last query will execute the 3rd and 4th query which has been explained above. After the execution of the 3rd query our array will be 5 5 0 5 5 . And after the execution of the 4th query i.e. execution of query 1, 2 and 3 our array will be 7 7 0 7 7 The above is the desired result
Query 1 is of type 1 : As stated above we will simply increment the array indices by 1 the given indices are 1 and 2 so after the execution of the first our array turns down to be 1 1 0 0 0 .
Query 2 is of type 1 : As stated above we will simply increment the array indices by 1 the given indices are 4 and 5 so after the execution of the first our array turns down to be 1 1 0 1 1 .
Query 3 is of type 2 : As stated in the definition of this type of query we will execute the queries stated in the range i.e. we will operate the queries instead of the array. The range given is 1 and 2 so we will execute queries 1 and 2 again i.e. we will use repetitive approach for the type 2 queries so we will execute query 1 again and our array will be 2 2 0 1 1. Now when we execute the query we will execute query 2 and our resultant array will be 2 2 0 2 2 .
Query 4 is of type 2 : As stated in the definition of this type of query we will execute the queries stated in the range i.e. we will operate the queries instead of the array. The range given is 1 and 3 so we will execute queries 1, 2 and 3 again i.e. using repetitive approach queries 1, 2 and 3 will be executed. After the execution of the query 1 again the array will be 3 3 0 2 2 . After the execution of the query 2 again the array will be 3 3 0 3 3 . Now due to query 3 inclusive in the range we will execute query 3 the resultant array will be 4 4 0 4 4 . As explained above.
Query 5 is of type 2 : The last query will execute the 3rd and 4th query which has been explained above. After the execution of the 3rd query our array will be 5 5 0 5 5 . And after the execution of the 4th query i.e. execution of query 1, 2 and 3 our array will be 7 7 0 7 7 The above is the desired result
Example 2 
Input : 1 2
        1 1 1
        1 1 1
Output : 2
Explanation of the example 2: Our array initially is of size 1 whose each element has been initialized to 0. So now the question states that we have 2 queries for the above example.  
Query 1 is of type 1 : As stated above we will simply increment the array indices by 1 the given indices are 1 and 1 so after the execution of the first our array turns down to be 1 .Query 2 is of type 1 : As stated above we will simply increment the array indices by 1 the given indices are 1 and 1 so after the execution of the first our array turns down to be 2 . This gives us the desired result
Query 1 is of type 1 : As stated above we will simply increment the array indices by 1 the given indices are 1 and 1 so after the execution of the first our array turns down to be 1 .
Query 2 is of type 1 : As stated above we will simply increment the array indices by 1 the given indices are 1 and 1 so after the execution of the first our array turns down to be 2 . This gives us the desired result
Method 1 : This method is the brute force method where by simple recursion is applied on the type 2 queries and for type 1 queries simple increment in the array index is performed. 
C++
Java
Python3
C#
Javascript
// CPP program to perform range queries over range// queries.#include <bits/stdc++.h>using namespace std; // Function to execute type 1 queryvoid type1(int arr[], int start, int limit){    // incrementing the array by 1 for type    // 1 queries    for (int i = start; i <= limit; i++)              arr[i]++;} // Function to execute type 2 queryvoid type2(int arr[], int query[][3], int start, int limit){    for (int i = start; i <= limit; i++) {         // If the query is of type 1 function        // call to type 1 query        if (query[i][0] == 1)            type1(arr, query[i][1], query[i][2]);                 // If the query is of type 2 recursive call        // to type 2 query        else if (query[i][0] == 2)            type2(arr, query, query[i][1], query[i][2]);           }} // Driver codeint main(){    // Input size of array and number of queries    int n = 5, m = 5;    int arr[n + 1];    for (int i = 1; i <= n; i++)        arr[i] = 0;         // Build query matrix    int temp[15] = { 1, 1, 2, 1, 4, 5, 2,                    1, 2, 2, 1, 3, 2, 3, 4 };    int query[5][3];    int j = 0;    for (int i = 1; i <= m; i++) {        query[i][0] = temp[j++];        query[i][1] = temp[j++];        query[i][2] = temp[j++];    }     // Perform queries    for (int i = 1; i <= m; i++)        if (query[i][0] == 1)            type1(arr, query[i][1], query[i][2]);        else if (query[i][0] == 2)            type2(arr, query, query[i][1], query[i][2]);            // printing the result    for (int i = 1; i <= n; i++)        cout << arr[i] << " ";         return 0;}
// Java program to perform range queries// over range queries.import java.util.*; class GFG{     // Function to execute type 1 query    static void type1(int[] arr, int start, int limit)    {         // incrementing the array by 1 for type        // 1 queries        for (int i = start; i <= limit; i++)            arr[i]++;    }     // Function to execute type 2 query    static void type2(int[] arr, int[][] query,                      int start, int limit)    {        for (int i = start; i <= limit; i++)        {             // If the query is of type 1 function            // call to type 1 query            if (query[i][0] == 1)                type1(arr, query[i][1], query[i][2]);             // If the query is of type 2 recursive call            // to type 2 query            else if (query[i][0] == 2)                type2(arr, query, query[i][1],                                  query[i][2]);        }    }     // Driver Code    public static void main(String[] args)    {         // Input size of array and number of queries        int n = 5, m = 5;        int[] arr = new int[n + 1];         // Build query matrix        int[] temp = { 1, 1, 2, 1, 4, 5, 2,                       1, 2, 2, 1, 3, 2, 3, 4 };        int[][] query = new int[6][4];        int j = 0;        for (int i = 1; i <= m; i++)        {            query[i][0] = temp[j++];            query[i][1] = temp[j++];            query[i][2] = temp[j++];        }         // Perform queries        for (int i = 1; i <= m; i++)            if (query[i][0] == 1)                type1(arr, query[i][1], query[i][2]);            else if (query[i][0] == 2)                type2(arr, query, query[i][1],                                  query[i][2]);         // printing the result        for (int i = 1; i <= n; i++)            System.out.print(arr[i] + " ");        System.out.println();    }} // This code is contributed by// sanjeev2552
# Python3 program to perform range# queries over range queries. # Function to execute type 1 querydef type1(arr, start, limit):         # incrementing the array by 1    # for type 1 queries    for i in range(start, limit + 1):        arr[i] += 1 # Function to execute type 2 querydef type2(arr, query, start, limit):     for i in range(start, limit + 1):         # If the query is of type 1        # function call to type 1 query        if (query[i][0] == 1):            type1(arr, query[i][1], query[i][2])         # If the query is of type 2        # recursive call to type 2 query        else if (query[i][0] == 2):            type2(arr, query, query[i][1],                              query[i][2]) # Driver code # Input size of array and# number of queriesn = 5m = 5arr = [0 for i in range(n + 1)] # Build query matrixtemp = [1, 1, 2, 1, 4, 5, 2,        1, 2, 2, 1, 3, 2, 3, 4 ] query = [[0 for i in range(3)]            for j in range(6)] j = 0for i in range(1, m + 1):    query[i][0] = temp[j]    j += 1    query[i][1] = temp[j]    j += 1    query[i][2] = temp[j]    j += 1 # Perform queriesfor i in range(1, m + 1):    if (query[i][0] == 1):        type1(arr, query[i][1],                   query[i][2])    else if (query[i][0] == 2):        type2(arr, query, query[i][1],                          query[i][2]) # printing the resultfor i in range(1, n + 1):    print(arr[i], end = " ") # This code is contributed# by mohit kumar
// C# program to perform range queries// over range queries.using System; class GFG{     // Function to execute type 1 query    static void type1(int[] arr, int start, int limit)    {         // incrementing the array by 1 for type        // 1 queries        for (int i = start; i <= limit; i++)            arr[i]++;    }     // Function to execute type 2 query    static void type2(int[] arr, int[,] query,                    int start, int limit)    {        for (int i = start; i <= limit; i++)        {             // If the query is of type 1 function            // call to type 1 query            if (query[i, 0] == 1)                type1(arr, query[i,1], query[i,2]);             // If the query is of type 2 recursive call            // to type 2 query            else if (query[i, 0] == 2)                type2(arr, query, query[i, 1],                                query[i, 2]);        }    }     // Driver Code    public static void Main()    {         // Input size of array and number of queries        int n = 5, m = 5;        int[] arr = new int[n + 1];         // Build query matrix        int[] temp = { 1, 1, 2, 1, 4, 5, 2,                    1, 2, 2, 1, 3, 2, 3, 4 };        int[,] query = new int[6,4];        int j = 0;        for (int i = 1; i <= m; i++)        {            query[i, 0] = temp[j++];            query[i, 1] = temp[j++];            query[i, 2] = temp[j++];        }         // Perform queries        for (int i = 1; i <= m; i++)            if (query[i, 0] == 1)                type1(arr, query[i, 1], query[i, 2]);            else if (query[i, 0] == 2)                type2(arr, query, query[i, 1],                                query[i, 2]);         // printing the result        for (int i = 1; i <= n; i++)            Console.Write(arr[i] + " ");        Console.WriteLine();    }} // This code is contributed by AbhiThakur
<script>// Javascript program to perform range queries// over range queries.         // Function to execute type 1 query    function type1(arr,start,limit)    {        // incrementing the array by 1 for type        // 1 queries        for (let i = start; i <= limit; i++)            arr[i]++;    }          // Function to execute type 2 query    function type2(arr,query,start,limit)    {        for (let i = start; i <= limit; i++)        {              // If the query is of type 1 function            // call to type 1 query            if (query[i][0] == 1)                type1(arr, query[i][1], query[i][2]);              // If the query is of type 2 recursive call            // to type 2 query            else if (query[i][0] == 2)                type2(arr, query, query[i][1],                                  query[i][2]);        }    }          // Driver Code    // Input size of array and number of queries        let n = 5, m = 5;        let arr = new Array(n + 1);         for(let i=0;i<arr.length;i++)        {            arr[i]=0;        }        // Build query matrix        let temp = [ 1, 1, 2, 1, 4, 5, 2,                       1, 2, 2, 1, 3, 2, 3, 4 ];        let query = new Array(6);        for(let i=0;i<6;i++)        {            query[i]=new Array(4);            for(let j=0;j<4;j++)            {                query[i][j]=0;            }        }        let j = 0;        for (let i = 1; i <= m; i++)        {            query[i][0] = temp[j++];            query[i][1] = temp[j++];            query[i][2] = temp[j++];        }          // Perform queries        for (let i = 1; i <= m; i++)            if (query[i][0] == 1)                type1(arr, query[i][1], query[i][2]);            else if (query[i][0] == 2)                type2(arr, query, query[i][1],                                  query[i][2]);          // printing the result        for (let i = 1; i <= n; i++)            document.write(arr[i] + " ");        document.write("<br>");      // This code is contributed by patel2127</script>
Output: 
7 7 0 7 7
The Time complexity of the above code is O(2 ^ m)
Method 2 : In this method we use an extra array for creating the record array to find the number of time a particular query is being executed and after creating the record array we simply execute the queries of type 1 and the contains of the record array is simply added to the main array the and this would give us the resultant array.
C++
Java
Python3
C#
Javascript
// CPP program to perform range queries over range// queries.#include <bits/stdc++.h>using namespace std; // Function to create the record arrayvoid record_sum(int record[], int l, int r,                           int n, int adder){    for (int i = l; i <= r; i++)        record[i] += adder;   } // Driver Codeint main(){    int n = 5, m = 5;    int arr[n];     // Build query matrix    memset(arr, 0, sizeof arr);    int query[5][3] = { { 1, 1, 2 }, { 1, 4, 5 },                         { 2, 1, 2 }, { 2, 1, 3 },                         { 2, 3, 4 } };    int record[m];    memset(record, 0, sizeof record);     for (int i = m - 1; i >= 0; i--) {         // If query is of type 2 then function        // call to record_sum        if (query[i][0] == 2)            record_sum(record, query[i][1] - 1,               query[i][2] - 1, m, record[i] + 1);                 // If query is of type 1 then simply add        // 1 to the record array        else            record_sum(record, i, i, m, 1);             }     // for type 1 queries adding the contains of    // record array to the main array record array    for (int i = 0; i < m; i++) {        if (query[i][0] == 1)            record_sum(arr, query[i][1] - 1,                 query[i][2] - 1, n, record[i]);           }     // printing the array    for (int i = 0; i < n; i++)        cout << arr[i] << ' ';         return 0;}
// Java program to perform range queries// over range queries.import java.util.Arrays; class GFG{     // Function to create the record array    static void record_sum(int record[], int l,                           int r, int n, int adder)    {        for (int i = l; i <= r; i++)        {            record[i] += adder;        }    }     // Driver Code    public static void main(String[] args)    {        int n = 5, m = 5;        int arr[] = new int[n];         // Build query matrix        Arrays.fill(arr, 0);        int query[][] = {{1, 1, 2}, {1, 4, 5},                         {2, 1, 2}, {2, 1, 3},                         {2, 3, 4}};        int record[] = new int[m];        Arrays.fill(record, 0);         for (int i = m - 1; i >= 0; i--)        {             // If query is of type 2 then function            // call to record_sum            if (query[i][0] == 2)            {                record_sum(record, query[i][1] - 1,                                   query[i][2] - 1, m,                                   record[i] + 1);            }                         // If query is of type 1 then            // simply add 1 to the record array            else            {                record_sum(record, i, i, m, 1);            }         }         // for type 1 queries adding the contains of        // record array to the main array record array        for (int i = 0; i < m; i++)        {            if (query[i][0] == 1)            {                record_sum(arr, query[i][1] - 1,                                query[i][2] - 1,                                n, record[i]);            }        }         // printing the array        for (int i = 0; i < n; i++)        {            System.out.print(arr[i] + " ");        }    }} // This code is contributed// by Princi Singh
# Python3 program to perform range queries over range# queries. # Function to create the record arraydef record_sum(record, l, r, n, adder):         for i in range(l, r + 1):        record[i] += adder # Driver Coden = 5m = 5arr = [0]*n # Build query matrixquery = [[1, 1, 2 ],[ 1, 4, 5 ],[2, 1, 2 ],        [ 2, 1, 3 ],[ 2, 3, 4]]record = [0]*m for i in range(m - 1, -1, -1):         # If query is of type 2 then function    # call to record_sum    if (query[i][0] == 2):        record_sum(record, query[i][1] - 1,                query[i][2] - 1, m, record[i] + 1)             # If query is of type 1 then simply add    # 1 to the record array    else:        record_sum(record, i, i, m, 1)         # for type 1 queries adding the contains of# record array to the main array record arrayfor i in range(m):    if (query[i][0] == 1):        record_sum(arr, query[i][1] - 1,            query[i][2] - 1, n, record[i]) # printing the arrayfor i in range(n):    print(arr[i], end=' ') # This code is contributed by shubhamsingh10
// C# program to perform range queries// over range queries.using System;     class GFG{     // Function to create the record array    static void record_sum(int []record, int l,                        int r, int n, int adder)    {        for (int i = l; i <= r; i++)        {            record[i] += adder;        }    }     // Driver Code    public static void Main(String[] args)    {        int n = 5, m = 5;        int []arr = new int[n];         // Build query matrix        int [,]query = {{1, 1, 2}, {1, 4, 5},                        {2, 1, 2}, {2, 1, 3},                        {2, 3, 4}};        int []record = new int[m];         for (int i = m - 1; i >= 0; i--)        {             // If query is of type 2 then function            // call to record_sum            if (query[i,0] == 2)            {                record_sum(record, query[i,1] - 1,                                query[i,2] - 1, m,                                record[i] + 1);            }                         // If query is of type 1 then            // simply add 1 to the record array            else            {                record_sum(record, i, i, m, 1);            }         }         // for type 1 queries adding the contains of        // record array to the main array record array        for (int i = 0; i < m; i++)        {            if (query[i, 0] == 1)            {                record_sum(arr, query[i, 1] - 1,                                query[i, 2] - 1,                                n, record[i]);            }        }         // printing the array        for (int i = 0; i < n; i++)        {            Console.Write(arr[i] + " ");        }    }} // This code is contributed by Rajput-Ji
<script>// Javascript program to perform range queries// over range queries.  // Function to create the record array    function record_sum(record,l,r,n,adder)    {        for (let i = l; i <= r; i++)        {            record[i] += adder;        }    }         // Driver Code    let n = 5, m = 5;    let arr = new Array(n);          // Build query matrix                 for(let i=0;i<arr.length;i++)        {            arr[i]=0;        }        let query = [[1, 1, 2], [1, 4, 5],                         [2, 1, 2], [2, 1, 3],                         [2, 3, 4]];        let record = new Array(m);        for(let i=0;i<record.length;i++)        {            record[i]=0;        }          for (let i = m - 1; i >= 0; i--)        {              // If query is of type 2 then function            // call to record_sum            if (query[i][0] == 2)            {                record_sum(record, query[i][1] - 1,                                   query[i][2] - 1, m,                                   record[i] + 1);            }                          // If query is of type 1 then            // simply add 1 to the record array            else            {                record_sum(record, i, i, m, 1);            }          }          // for type 1 queries adding the contains of        // record array to the main array record array        for (let i = 0; i < m; i++)        {            if (query[i][0] == 1)            {                record_sum(arr, query[i][1] - 1,                                query[i][2] - 1,                                n, record[i]);            }        }          // printing the array        for (let i = 0; i < n; i++)        {            document.write(arr[i] + " ");        }      // This code is contributed by unknown2108</script>
Output : 
7 7 0 7 7
The Time complexity of the above code is O(n^2) 
Method 3 : This method has been made more efficient by applying square root decomposition to the record array. 
C++
Java
Python3
C#
Javascript
// CPP program to perform range queries over range// queries.#include <bits/stdc++.h>#define max 10000using namespace std; // For prefix sum arrayvoid update(int arr[], int l){    arr[l] += arr[l - 1];} // This function is used to apply square root// decomposition in the record arrayvoid record_func(int block_size, int block[],         int record[], int l, int r, int value){    // traversing first block in range    while (l < r && l % block_size != 0 && l != 0) {        record[l] += value;        l++;    }    // traversing completely overlapped blocks in range    while (l + block_size <= r + 1) {        block[l / block_size] += value;        l += block_size;    }    // traversing last block in range    while (l <= r) {        record[l] += value;        l++;    }}// Function to print the resultant arrayvoid print(int arr[], int n){    for (int i = 0; i < n; i++)        cout << arr[i] << " ";   } // Driver codeint main(){    int n = 5, m = 5;    int arr[n], record[m];    int block_size = sqrt(m);    int block[max];    int command[5][3] = { { 1, 1, 2 }, { 1, 4, 5 },                          { 2, 1, 2 }, { 2, 1, 3 },                          { 2, 3, 4 } };    memset(arr, 0, sizeof arr);    memset(record, 0, sizeof record);    memset(block, 0, sizeof block);     for (int i = m - 1; i >= 0; i--) {         // If query is of type 2 then function        // call to record_func        if (command[i][0] == 2) {            int x = i / (block_size);            record_func(block_size, block, record,                        command[i][1] - 1, command[i][2] - 1,                        (block[x] + record[i] + 1));        }        // If query is of type 1 then simply add        // 1 to the record array        else            record[i]++;           }     // Merging the value of the block in the record array    for (int i = 0; i < m; i++) {        int check = (i / block_size);        record[i] += block[check];    }     for (int i = 0; i < m; i++) {        // If query is of type 1 then the array        // elements are over-written by the record        //  array        if (command[i][0] == 1) {            arr[command[i][1] - 1] += record[i];            if ((command[i][2] - 1) < n - 1)                arr[(command[i][2])] -= record[i];                   }    }     // The prefix sum of the array    for (int i = 1; i < n; i++)        update(arr, i);         // Printing the resultant array    print(arr, n);    return 0;}
// Java program to perform range queries over range// queries.public class GFG {     static final int max = 10000; // For prefix sum array    static void update(int arr[], int l) {        arr[l] += arr[l - 1];    } // This function is used to apply square root// decomposition in the record array    static void record_func(int block_size, int block[],            int record[], int l, int r, int value) {        // traversing first block in range        while (l < r && l % block_size != 0 && l != 0) {            record[l] += value;            l++;        }        // traversing completely overlapped blocks in range        while (l + block_size <= r + 1) {            block[l / block_size] += value;            l += block_size;        }        // traversing last block in range        while (l <= r) {            record[l] += value;            l++;        }    }// Function to print the resultant array     static void print(int arr[], int n) {        for (int i = 0; i < n; i++) {            System.out.print(arr[i] + " ");        }    } // Driver code    public static void main(String[] args) {         int n = 5, m = 5;        int arr[] = new int[n], record[] = new int[m];        int block_size = (int) Math.sqrt(m);        int block[] = new int[max];        int command[][] = {{1, 1, 2}, {1, 4, 5},        {2, 1, 2}, {2, 1, 3},        {2, 3, 4}};         for (int i = m - 1; i >= 0; i--) {             // If query is of type 2 then function            // call to record_func            if (command[i][0] == 2) {                int x = i / (block_size);                record_func(block_size, block, record,                        command[i][1] - 1, command[i][2] - 1,                        (block[x] + record[i] + 1));            } // If query is of type 1 then simply add            // 1 to the record array            else {                record[i]++;            }        }         // Merging the value of the block in the record array        for (int i = 0; i < m; i++) {            int check = (i / block_size);            record[i] += block[check];        }         for (int i = 0; i < m; i++) {            // If query is of type 1 then the array            // elements are over-written by the record            //  array            if (command[i][0] == 1) {                arr[command[i][1] - 1] += record[i];                if ((command[i][2] - 1) < n - 1) {                    arr[(command[i][2])] -= record[i];                }            }        }         // The prefix sum of the array        for (int i = 1; i < n; i++) {            update(arr, i);        }         // Printing the resultant array        print(arr, n);     } }// This code is contributed by 29AjayKumar
# Python3 program to perform range# queries over range queries.import math max = 10000 # For prefix sum arraydef update(arr, l):         arr[l] += arr[l - 1] # This function is used to apply square root# decomposition in the record arraydef record_func(block_size, block,                record, l, r, value):     # Traversing first block in range    while (l < r and           l % block_size != 0 and           l != 0):        record[l] += value        l += 1     # Traversing completely overlapped    # blocks in range    while (l + block_size <= r + 1):        block[l // block_size] += value        l += block_size     # Traversing last block in range    while (l <= r):        record[l] += value        l += 1 # Function to print the resultant arraydef print_array(arr, n):         for i in range(n):        print(arr[i], end = " ") # Driver codeif __name__ == "__main__":     n = 5    m = 5    arr = [0] * n    record = [0] * m         block_size = (int)(math.sqrt(m))    block = [0] * max         command = [ [ 1, 1, 2 ],                [ 1, 4, 5 ],                [ 2, 1, 2 ],                [ 2, 1, 3 ],                [ 2, 3, 4 ] ]     for i in range(m - 1, -1, -1):         # If query is of type 2 then function        # call to record_func        if (command[i][0] == 2):            x = i // (block_size)                         record_func(block_size, block,                        record, command[i][1] - 1,                                command[i][2] - 1,                        (block[x] + record[i] + 1))         # If query is of type 1 then simply add        # 1 to the record array        else:            record[i] += 1     # Merging the value of the block    # in the record array    for i in range(m):        check = (i // block_size)        record[i] += block[check]     for i in range(m):                 # If query is of type 1 then the array        # elements are over-written by the record        # array        if (command[i][0] == 1):            arr[command[i][1] - 1] += record[i]                         if ((command[i][2] - 1) < n - 1):                arr[(command[i][2])] -= record[i]     # The prefix sum of the array    for i in range(1, n):        update(arr, i)     # Printing the resultant array    print_array(arr, n) # This code is contributed by chitranayal
// C# program to perform range queries over range// queries.using System;public class GFG {      static readonly int max = 10000;  // For prefix sum array    static void update(int []arr, int l) {        arr[l] += arr[l - 1];    }  // This function is used to apply square root// decomposition in the record array    static void record_func(int block_size, int []block,            int []record, int l, int r, int value) {        // traversing first block in range        while (l < r && l % block_size != 0 && l != 0) {            record[l] += value;            l++;        }        // traversing completely overlapped blocks in range        while (l + block_size <= r + 1) {            block[l / block_size] += value;            l += block_size;        }        // traversing last block in range        while (l <= r) {            record[l] += value;            l++;        }    }// Function to print the resultant array      static void print(int []arr, int n) {        for (int i = 0; i < n; i++) {            Console.Write(arr[i] + " ");        }    }  // Driver code    public static void Main() {          int n = 5, m = 5;        int []arr = new int[n]; int []record = new int[m];        int block_size = (int) Math.Sqrt(m);        int []block = new int[max];        int [,]command= {{1, 1, 2}, {1, 4, 5},        {2, 1, 2}, {2, 1, 3},        {2, 3, 4}};          for (int i = m - 1; i >= 0; i--) {              // If query is of type 2 then function            // call to record_func            if (command[i,0] == 2) {                int x = i / (block_size);                record_func(block_size, block, record,                        command[i,1] - 1, command[i,2] - 1,                        (block[x] + record[i] + 1));            } // If query is of type 1 then simply add            // 1 to the record array            else {                record[i]++;            }        }          // Merging the value of the block in the record array        for (int i = 0; i < m; i++) {            int check = (i / block_size);            record[i] += block[check];        }          for (int i = 0; i < m; i++) {            // If query is of type 1 then the array            // elements are over-written by the record            //  array            if (command[i,0] == 1) {                arr[command[i,1] - 1] += record[i];                if ((command[i,2] - 1) < n - 1) {                    arr[(command[i,2])] -= record[i];                }            }        }          // The prefix sum of the array        for (int i = 1; i < n; i++) {            update(arr, i);        }          // Printing the resultant array        print(arr, n);      }  }// This code is contributed by 29AjayKumar
<script>// Javascript program to perform range queries over range// queries. let max = 10000; // For prefix sum arrayfunction update(arr,l){    arr[l] += arr[l - 1];} // This function is used to apply square root// decomposition in the record arrayfunction record_func(block_size,block,record,l,r,value){    // traversing first block in range        while (l < r && l % block_size != 0 && l != 0) {            record[l] += value;            l++;        }        // traversing completely overlapped blocks in range        while (l + block_size <= r + 1) {            let x = Math.floor(l / block_size);            block[x] += value;            l += block_size;        }        // traversing last block in range        while (l <= r) {            record[l] += value;            l++;        }} // Function to print the resultant arrayfunction print(arr,n){    for (let i = 0; i < n; i++) {            document.write(arr[i] + " ");        }} // Driver codelet n = 5, m = 5;        let arr = new Array(n);        for(let i = 0; i < n; i++)            arr[i] = 0;        let record = new Array(m);        for(let i = 0; i < m; i++)            record[i] = 0;        let block_size = Math.floor( Math.sqrt(m));        let block = new Array(max);        for(let i = 0; i < max; i++)            block[i] = 0;        let command = [[1, 1, 2], [1, 4, 5],        [2, 1, 2], [2, 1, 3],        [2, 3, 4]];          for (let i = m - 1; i >= 0; i--) {              // If query is of type 2 then function            // call to record_func            if (command[i][0] == 2)            {                let x = Math.floor(i / (block_size));                record_func(block_size, block, record,                        command[i][1] - 1, command[i][2] - 1,                        (block[x] + record[i] + 1));            }                         // If query is of type 1 then simply add            // 1 to the record array            else {                record[i]++;            }        }          // Merging the value of the block in the record array        for (let i = 0; i < m; i++) {            let check = Math.floor(i / block_size);            record[i] += block[check];        }          for (let i = 0; i < m; i++)        {                     // If query is of type 1 then the array            // elements are over-written by the record            //  array            if (command[i][0] == 1) {                arr[command[i][1] - 1] += record[i];                if ((command[i][2] - 1) < n - 1) {                    arr[(command[i][2])] -= record[i];                }            }        }          // The prefix sum of the array        for (let i = 1; i < n; i++) {            update(arr, i);        }          // Printing the resultant array        print(arr, n); // This code is contributed by ab2127</script>
Output :  
7 7 0 7 7
Method 4 : This method has been made more efficient by applying Binary Indexed Tree or Fenwick Tree by creating two binary indexed tree for query 1 and query 2 respectively. 
C++
Java
C#
// C++ program to perform range queries over range// queries.#include <bits/stdc++.h>using namespace std; // Updates a node in Binary Index Tree (BITree) at given index// in BITree.  The given value 'val' is added to BITree[i] and// all of its ancestors in tree.void updateBIT(int BITree[], int n, int index, int val){    // index in BITree[] is 1 more than the index in arr[]    index = index + 1;     // Traverse all ancestors and add 'val'    while (index <= n) {         // Add 'val' to current node of BI Tree        BITree[index] = (val + BITree[index]);         // Update index to that of parent in update View        index = (index + (index & (-index)));    }    return;} // Constructs and returns a Binary Indexed Tree for given// array of size n.int* constructBITree(int n){    // Create and initialize BITree[] as 0    int* BITree = new int[n + 1];    for (int i = 1; i <= n; i++)        BITree[i] = 0;         return BITree;} // Returns sum of arr[0..index]. This function assumes// that the array is preprocessed and partial sums of// array elements are stored in BITree[]int getSum(int BITree[], int index){    int sum = 0;    // index in BITree[] is 1 more than the index in arr[]    index = index + 1;     // Traverse ancestors of BITree[index]    while (index > 0) {         // Add element of BITree to sum        sum = (sum + BITree[index]);         // Move index to parent node in getSum View        index -= index & (-index);    }    return sum;} // Function to update the BITreevoid update(int BITree[], int l, int r, int n, int val){    updateBIT(BITree, n, l, val);    updateBIT(BITree, n, r + 1, -val);    return;} // Driver codeint main(){    int n = 5, m = 5;    int temp[15] = { 1, 1, 2, 1, 4, 5, 2, 1, 2,                            2, 1, 3, 2, 3, 4 };    int q[5][3];    int j = 0;    for (int i = 1; i <= m; i++) {        q[i][0] = temp[j++];        q[i][1] = temp[j++];        q[i][2] = temp[j++];    }     // BITree for query of type 2    int* BITree = constructBITree(m);     // BITree for query of type 1    int* BITree2 = constructBITree(n);     // Input the queries in a 2D matrix    for (int i = 1; i <= m; i++)        cin >> q[i][0] >> q[i][1] >> q[i][2];          // If query is of type 2 then function call     // to update with BITree    for (int i = m; i >= 1; i--)               if (q[i][0] == 2)            update(BITree, q[i][1] - 1, q[i][2] - 1, m, 1);         for (int i = m; i >= 1; i--) {        if (q[i][0] == 2) {            long int val = getSum(BITree, i - 1);            update(BITree, q[i][1] - 1, q[i][2] - 1, m, val);        }    }     // If query is of type 1 then function call    // to update with BITree2    for (int i = m; i >= 1; i--) {               if (q[i][0] == 1) {            long int val = getSum(BITree, i - 1);            update(BITree2, q[i][1] - 1, q[i][2] - 1,                    n, (val + 1));        }    }     for (int i = 1; i <= n; i++)        cout << (getSum(BITree2, i - 1)) << " ";         return 0;}
// Java program to perform range queries over range// queries.import java.io.*;import java.util.*;class GFG{   // Updates a node in Binary Index Tree (BITree) at given index  // in BITree.  The given value 'val' is added to BITree[i] and  // all of its ancestors in tree.  static void updateBIT(int BITree[], int n, int index, int val)  {     // index in BITree[] is 1 more than the index in arr[]    index = index + 1;     // Traverse all ancestors and add 'val'    while (index <= n)    {       // Add 'val' to current node of BI Tree      BITree[index] = (val + BITree[index]);       // Update index to that of parent in update View      index = (index + (index & (-index)));    }    return;  }   // Constructs and returns a Binary Indexed Tree for given  // array of size n.  static int[] constructBITree(int n)  {     // Create and initialize BITree[] as 0    int[] BITree = new int[n + 1];    for (int i = 1; i <= n; i++)       BITree[i] = 0;     return BITree;  }   // Returns sum of arr[0..index]. This function assumes  // that the array is preprocessed and partial sums of  // array elements are stored in BITree[]  static int getSum(int BITree[], int index)  {    int sum = 0;     // index in BITree[] is 1 more than the index in arr[]    index = index + 1;     // Traverse ancestors of BITree[index]    while (index > 0)    {       // Add element of BITree to sum      sum = (sum + BITree[index]);       // Move index to parent node in getSum View      index -= index & (-index);    }    return sum;  }   // Function to update the BITree  static void update(int BITree[], int l, int r, int n, int val)  {    updateBIT(BITree, n, l, val);    updateBIT(BITree, n, r + 1, -val);    return;  }   // Driver code  public static void main (String[] args)  {     int n = 5, m = 5;    int temp[] = { 1, 1, 2, 1, 4, 5, 2, 1, 2,                  2, 1, 3, 2, 3, 4 };    int[][] q = new int[6][3];    int j = 0;    for (int i = 1; i <= m; i++) {      q[i][0] = temp[j++];      q[i][1] = temp[j++];      q[i][2] = temp[j++];    }     // BITree for query of type 2    int[] BITree = constructBITree(m);     // BITree for query of type 1    int[] BITree2 = constructBITree(n);     // Input the queries in a 2D matrix    /*Scanner sc=new Scanner(System.in);        for (int i = 1; i <= m; i++)         {            q[i][0]=sc.nextInt();            q[i][1]=sc.nextInt();            q[i][2]=sc.nextInt();        }*/     // If query is of type 2 then function call     // to update with BITree    for (int i = m; i >= 1; i--)              if (q[i][0] == 2)        update(BITree, q[i][1] - 1, q[i][2] - 1, m, 1);     for (int i = m; i >= 1; i--) {      if (q[i][0] == 2) {        int val = getSum(BITree, i - 1);        update(BITree, q[i][1] - 1, q[i][2] - 1, m, val);      }    }     // If query is of type 1 then function call     // to update with BITree2    for (int i = m; i >= 1; i--) {              if (q[i][0] == 1) {        int val = getSum(BITree, i - 1);        update(BITree2, q[i][1] - 1, q[i][2] - 1,               n, (val + 1));      }    }     for (int i = 1; i <= n; i++)       System.out.print(getSum(BITree2, i - 1)+" ");   }} // This code is contributed by avanitrachhadiya2155
// C# program to perform range queries over range// queries.using System; class GFG{     // Updates a node in Binary Index Tree (BITree)// at given index in BITree.  The given value// 'val' is added to BITree[i] and// all of its ancestors in tree.static void updateBIT(int[] BITree, int n,                      int index, int val){     // index in BITree[] is 1 more than    // the index in arr[]    index = index + 1;         // Traverse all ancestors and add 'val'    while (index <= n)    {                 // Add 'val' to current node of BI Tree        BITree[index] = (val + BITree[index]);                 // Update index to that of parent in update View        index = (index + (index & (-index)));    }    return;} // Constructs and returns a Binary Indexed// Tree for given array of size n.static int[] constructBITree(int n){     // Create and initialize BITree[] as 0    int[] BITree = new int[n + 1];    for(int i = 1; i <= n; i++)         BITree[i] = 0;         return BITree;}  // Returns sum of arr[0..index]. This function assumes// that the array is preprocessed and partial sums of// array elements are stored in BITree[]static int getSum(int[] BITree, int index){    int sum = 0;         // index in BITree[] is 1 more than    // the index in arr[]    index = index + 1;         // Traverse ancestors of BITree[index]    while (index > 0)    {                 // Add element of BITree to sum        sum = (sum + BITree[index]);                 // Move index to parent node in getSum View        index -= index & (-index);    }    return sum;} // Function to update the BITreestatic void update(int[] BITree, int l, int r,                   int n, int val){    updateBIT(BITree, n, l, val);    updateBIT(BITree, n, r + 1, -val);    return;} // Driver codestatic public void Main(){    int n = 5, m = 5;    int[] temp = { 1, 1, 2, 1, 4, 5, 2,                   1, 2, 2, 1, 3, 2, 3, 4 };    int[,] q = new int[6, 3];    int j = 0;         for(int i = 1; i <= m; i++)    {        q[i, 0] = temp[j++];        q[i, 1] = temp[j++];        q[i, 2] = temp[j++];    }         // BITree for query of type 2    int[] BITree = constructBITree(m);         // BITree for query of type 1    int[] BITree2 = constructBITree(n);     // If query is of type 2 then function call     // to update with BITree    for(int i = m; i >= 1; i--)                if (q[i, 0] == 2)            update(BITree, q[i, 1] - 1,                           q[i, 2] - 1, m, 1);         for(int i = m; i >= 1; i--)    {        if (q[i,0] == 2)        {            int val = getSum(BITree, i - 1);            update(BITree, q[i, 1] - 1,                           q[i, 2] - 1, m, val);        }    }         // If query is of type 1 then function call     // to update with BITree2    for(int i = m; i >= 1; i--)    {                if (q[i,0] == 1)        {            int val = getSum(BITree, i - 1);            update(BITree2, q[i, 1] - 1, q[i, 2] - 1,                            n, (val + 1));        }    }         for(int i = 1; i <= n; i++)         Console.Write(getSum(BITree2, i - 1) + " ");}} // This code is contributed by rag2127
Output : 
7 7 0 7 7
The Time complexity of Method 3 and Method 4 is O(log n).
This article is contributed by Mohak Agrawal.If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
29AjayKumar
mohit kumar 29
princi singh
Rajput-Ji
sanjeev2552
SHUBHAMSINGH10
abhaysingh290895
ukasp
avanitrachhadiya2155
rag2127
patel2127
unknown2108
ab2127
simmytarika5
array-range-queries
Binary Indexed Tree
Arrays
Competitive Programming
Arrays
Binary Indexed Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Arrays in Java
Arrays in C/C++
Write a program to reverse an array or string
Program for array rotation
Largest Sum Contiguous Subarray
Competitive Programming - A Complete Guide
Practice for cracking any coding interview
Arrow operator -> in C/C++ with Examples
Breadth First Traversal ( BFS ) on a 2D array
Prefix Sum Array - Implementation and Applications in Competitive Programming