Given an array arr[] consisting of N 0s and a 2D array Q[][] consisting of queries of the following two types:
- 1 L R X: Increment all the elements in the range [L, R] by X.
- 2 X: Print elements at Xth index of the array.
Input: arr[] = { 0, 0, 0, 0, 0 }, Q[][] = { { 1, 0, 2, 100 }, { 2, 1 }, { 1, 2, 3, 200 }, { 2, 2 }, {
4 } }
Output: 100 300 0
Explanation:
Query1: Incrementing all the array elements in the range [0, 2] by 100 modifies arr[] to { 100, 100, 100, 0, 0 }.
Query2: Print arr[1](=100)
Query3: Incrementing all the array elements in the range [2, 3] by 200 modifies arr[] to { 100, 100, 300, 200, 0 }.
Query4: Print arr[2](=300)
Query5: Print arr[4](=0)Input: arr[] = { 0, 0 }, Q[][] = { { 1, 0, 1, 100 }, { 2, 1 } }
Output: 100
Approach: The idea is to use the concept of Segment Tree to perform queries of type 2 and the difference array to perform queries of type 1. Follow the steps below to solve the problem:
- For query of type { 1, L, R, X }, update arr[L] += X and arr[R + 1] -= X using Segment tree.
- For query of type { 2, X } Find the sum of array elements in the range [0, X] using Segment Tree and print the sum obtained.
Below is the implementation of the above approach:
// C++ program to implement // the above approach #include <bits/stdc++.h> using namespace std;
// Function to update the array elements // at idx pos, i.e arr[pos] += X void update( int Tree[], int idx, int s,
int e, int pos, int X)
{ // If current node is a
// leaf nodes
if (s == e) {
// Update Tree[idx]
Tree[idx] += X;
}
else {
// Divide segment tree into left
// and right subtree
int m = (s + e) / 2;
// Check if pos lies in left subtree
if (pos <= m) {
// Search pos in left subtree
update(Tree, 2 * idx, s, m, pos, X);
}
else {
// Search pos in right subtree
update(Tree, 2 * idx + 1, m + 1, e,
pos, X);
}
// Update Tree[idx]
Tree[idx]
= Tree[2 * idx] + Tree[2 * idx + 1];
}
} // Function to find the sum from // elements in the range [0, X] int sum( int Tree[], int idx, int s,
int e, int ql, int qr)
{ // Check if range[ql, qr] equals
// to range [s, e]
if (ql == s && qr == e)
return Tree[idx];
if (ql > qr)
return 0;
// Divide segment tree into
// left subtree and
// right subtree
int m = (s + e) / 2;
// Return sum of elements in the range[ql, qr]
return sum(Tree, 2 * idx, s, m, ql, min(m, qr))
+ sum(Tree, 2 * idx + 1, m + 1, e,
max(ql, m + 1), qr);
} // Function to find Xth element // in the array void getElement( int Tree[], int X, int N)
{ // Print element at index x
cout << "Element at " << X << " is "
<< sum(Tree, 1, 0, N - 1, 0, X) << endl;
} // Function to update array elements // in the range [L, R] void range_Update( int Tree[], int L,
int R, int X, int N)
{ // Update arr[l] += X
update(Tree, 1, 0, N - 1, L, X);
// Update arr[R + 1] += X
if (R + 1 < N)
update(Tree, 1, 0, N - 1, R + 1, -X);
} // Drivers Code int main()
{ // Size of array
int N = 5;
int Tree[4 * N + 5] = { 0 };
int arr[] = { 0, 0 };
vector<vector< int > >
Q = { { 1, 0, 1, 100 }, { 2, 1 } };
int cntQuery = Q.size();
for ( int i = 0; i < cntQuery; i++) {
if (Q[i][0] == 1) {
range_Update(Tree, Q[i][1],
Q[i][2], Q[i][3], N);
}
else {
getElement(Tree, Q[i][1], N);
}
}
} |
// Java program to implement // the above approach import java.util.*;
class GFG
{ // Function to update the array elements // at idx pos, i.e arr[pos] += X static void update( int Tree[], int idx, int s,
int e, int pos, int X)
{ // If current node is a
// leaf nodes
if (s == e)
{
// Update Tree[idx]
Tree[idx] += X;
}
else
{
// Divide segment tree into left
// and right subtree
int m = (s + e) / 2 ;
// Check if pos lies in left subtree
if (pos <= m)
{
// Search pos in left subtree
update(Tree, 2 * idx, s, m, pos, X);
}
else
{
// Search pos in right subtree
update(Tree, 2 * idx + 1 , m + 1 , e,
pos, X);
}
// Update Tree[idx]
Tree[idx]
= Tree[ 2 * idx] + Tree[ 2 * idx + 1 ];
}
} // Function to find the sum from // elements in the range [0, X] static int sum( int Tree[], int idx, int s,
int e, int ql, int qr)
{ // Check if range[ql, qr] equals
// to range [s, e]
if (ql == s && qr == e)
return Tree[idx];
if (ql > qr)
return 0 ;
// Divide segment tree into
// left subtree and
// right subtree
int m = (s + e) / 2 ;
// Return sum of elements in the range[ql, qr]
return sum(Tree, 2 * idx, s, m, ql, Math.min(m, qr))
+ sum(Tree, 2 * idx + 1 , m + 1 , e,
Math.max(ql, m + 1 ), qr);
} // Function to find Xth element // in the array static void getElement( int Tree[], int X, int N)
{ // Print element at index x
System.out.print( "Element at " + X+ " is "
+ sum(Tree, 1 , 0 , N - 1 , 0 , X) + "\n" );
} // Function to update array elements // in the range [L, R] static void range_Update( int Tree[], int L,
int R, int X, int N)
{ // Update arr[l] += X
update(Tree, 1 , 0 , N - 1 , L, X);
// Update arr[R + 1] += X
if (R + 1 < N)
update(Tree, 1 , 0 , N - 1 , R + 1 , -X);
} // Drivers Code public static void main(String[] args)
{ // Size of array
int N = 5 ;
int Tree[] = new int [ 4 * N + 5 ];
int arr[] = { 0 , 0 };
int [][]
Q = { { 1 , 0 , 1 , 100 }, { 2 , 1 } };
int cntQuery = Q.length;
for ( int i = 0 ; i < cntQuery; i++)
{
if (Q[i][ 0 ] == 1 )
{
range_Update(Tree, Q[i][ 1 ],
Q[i][ 2 ], Q[i][ 3 ], N);
}
else
{
getElement(Tree, Q[i][ 1 ], N);
}
}
} } // This code is contributed by shikhasingrajput |
# Python3 program to implement # the above approach # Function to update the array elements # at idx pos, i.e arr[pos] += X def update(Tree, idx, s, e, pos, X):
# If current node is a
# leaf nodes
if (s = = e):
# Update Tree[idx]
Tree[idx] + = X
else :
# Divide segment tree into left
# and right subtree
m = (s + e) / / 2
# Check if pos lies in left subtree
if (pos < = m):
# Search pos in left subtree
update(Tree, 2 * idx, s, m, pos, X)
else :
# Search pos in right subtree
update(Tree, 2 * idx + 1 , m + 1 , e,pos, X)
# Update Tree[idx]
Tree[idx] = Tree[ 2 * idx] + Tree[ 2 * idx + 1 ]
# Function to find the sum from # elements in the range [0, X] def sum (Tree, idx, s, e, ql, qr):
# Check if range[ql, qr] equals
# to range [s, e]
if (ql = = s and qr = = e):
return Tree[idx]
if (ql > qr):
return 0
# Divide segment tree into
# left subtree and
# right subtree
m = (s + e) / / 2
# Return sum of elements in the range[ql, qr]
return sum (Tree, 2 * idx, s, m, ql, min (m, qr)) + sum (Tree, 2 * idx + 1 , m + 1 , e, max (ql, m + 1 ), qr)
# Function to find Xth element # in the array def getElement(Tree, X, N):
# Print element at index x
print ( "Element at" , X, "is " , sum (Tree, 1 , 0 , N - 1 , 0 , X))
# Function to update array elements # in the range [L, R] def range_Update(Tree, L, R, X, N):
# Update arr[l] += X
update(Tree, 1 , 0 , N - 1 , L, X)
# Update arr[R + 1] += X
if (R + 1 < N):
update(Tree, 1 , 0 , N - 1 , R + 1 , - X)
# Drivers Code if __name__ = = '__main__' :
# Size of array
N = 5
Tree = [ 0 ] * ( 4 * N + 5 )
arr = [ 0 , 0 ]
Q = [ [ 1 , 0 , 1 , 100 ], [ 2 , 1 ] ]
cntQuery = len (Q)
for i in range (cntQuery):
if (Q[i][ 0 ] = = 1 ):
range_Update(Tree, Q[i][ 1 ], Q[i][ 2 ], Q[i][ 3 ], N)
else :
getElement(Tree, Q[i][ 1 ], N)
# This code is contributed by mohit kumar 29. |
// C# program to implement // the above approach using System;
public class GFG
{ // Function to update the array elements
// at idx pos, i.e arr[pos] += X
static void update( int []Tree, int idx, int s,
int e, int pos, int X)
{
// If current node is a
// leaf nodes
if (s == e)
{
// Update Tree[idx]
Tree[idx] += X;
}
else
{
// Divide segment tree into left
// and right subtree
int m = (s + e) / 2;
// Check if pos lies in left subtree
if (pos <= m)
{
// Search pos in left subtree
update(Tree, 2 * idx, s, m, pos, X);
}
else
{
// Search pos in right subtree
update(Tree, 2 * idx + 1, m + 1, e,
pos, X);
}
// Update Tree[idx]
Tree[idx]
= Tree[2 * idx] + Tree[2 * idx + 1];
}
}
// Function to find the sum from
// elements in the range [0, X]
static int sum( int []Tree, int idx, int s,
int e, int ql, int qr)
{
// Check if range[ql, qr] equals
// to range [s, e]
if (ql == s && qr == e)
return Tree[idx];
if (ql > qr)
return 0;
// Divide segment tree into
// left subtree and
// right subtree
int m = (s + e) / 2;
// Return sum of elements in the range[ql, qr]
return sum(Tree, 2 * idx, s, m, ql, Math.Min(m, qr))
+ sum(Tree, 2 * idx + 1, m + 1, e,
Math.Max(ql, m + 1), qr);
}
// Function to find Xth element
// in the array
static void getElement( int []Tree, int X, int N)
{
// Print element at index x
Console.Write( "Element at " + X+ " is "
+ sum(Tree, 1, 0, N - 1, 0, X) + "\n" );
}
// Function to update array elements
// in the range [L, R]
static void range_Update( int []Tree, int L,
int R, int X, int N)
{
// Update arr[l] += X
update(Tree, 1, 0, N - 1, L, X);
// Update arr[R + 1] += X
if (R + 1 < N)
update(Tree, 1, 0, N - 1, R + 1, -X);
}
// Drivers Code
public static void Main(String[] args)
{
// Size of array
int N = 5;
int []Tree = new int [4 * N + 5];
int []arr = { 0, 0 };
int [,]Q = { { 1, 0, 1, 100 }, { 2, 1, 0, 0 } };
int cntQuery = Q.GetLength(0);
for ( int i = 0; i < cntQuery; i++)
{
if (Q[i, 0] == 1)
{
range_Update(Tree, Q[i, 1],
Q[i, 2], Q[i, 3], N);
}
else
{
getElement(Tree, Q[i, 1], N);
}
}
}
} // This code is contributed by 29AjayKumar |
<script> // Javascript program to implement // the above approach // Function to update the array elements // at idx pos, i.e arr[pos] += X function update(Tree, idx, s, e, pos, X)
{ // If current node is a
// leaf nodes
if (s == e) {
// Update Tree[idx]
Tree[idx] += X;
}
else {
// Divide segment tree into left
// and right subtree
var m = parseInt((s + e) / 2);
// Check if pos lies in left subtree
if (pos <= m) {
// Search pos in left subtree
update(Tree, 2 * idx, s, m, pos, X);
}
else {
// Search pos in right subtree
update(Tree, 2 * idx + 1, m + 1, e,
pos, X);
}
// Update Tree[idx]
Tree[idx]
= Tree[2 * idx] + Tree[2 * idx + 1];
}
} // Function to find the sum from // elements in the range [0, X] function sum(Tree, idx, s, e, ql, qr)
{ // Check if range[ql, qr] equals
// to range [s, e]
if (ql == s && qr == e)
return Tree[idx];
if (ql > qr)
return 0;
// Divide segment tree into
// left subtree and
// right subtree
var m =parseInt((s + e) / 2);
// Return sum of elements in the range[ql, qr]
return sum(Tree, 2 * idx, s, m, ql, Math.min(m, qr))
+ sum(Tree, 2 * idx + 1, m + 1, e,
Math.max(ql, m + 1), qr);
} // Function to find Xth element // in the array function getElement(Tree, X, N)
{ // Print element at index x
document.write( "Element at " + X + " is "
+ sum(Tree, 1, 0, N - 1, 0, X) );
} // Function to update array elements // in the range [L, R] function range_Update(Tree, L, R, X, N)
{ // Update arr[l] += X
update(Tree, 1, 0, N - 1, L, X);
// Update arr[R + 1] += X
if (R + 1 < N)
update(Tree, 1, 0, N - 1, R + 1, -X);
} // Drivers Code // Size of array var N = 5;
var Tree = Array(4 * N + 5).fill(0);
var arr = [ 0, 0 ];
var Q = [[ 1, 0, 1, 100 ], [ 2, 1 ]];
var cntQuery = Q.length;
for ( var i = 0; i < cntQuery; i++) {
if (Q[i][0] == 1) {
range_Update(Tree, Q[i][1],
Q[i][2], Q[i][3], N);
}
else {
getElement(Tree, Q[i][1], N);
}
} </script> |
Element at 1 is 100
Time Complexity: O(|Q| * log(N))
Auxiliary Space: O(N)