Difference Array | Range update query in O(1)
Last Updated :
05 Jul, 2025
Given an array arr[] and a 2D array opr[][], where each row represents an operation in the form [l, r, v]. For each operation, add v to all elements from index l to r in arr. Return the updated array after applying all operations.
Examples :
Input: arr[] = [2, 3, 5, 6, 7], opr[][] = [[2, 4, 2], [3, 4, -1]]
Output: [2, 3, 7, 7, 8]
Explanation: Operation [2, 4, 2]: Add 2 to elements at indices 2 to 4.
Updated array: [2, 3, 7, 8, 9]
Operation [3, 4, -1]: Subtract 1 from elements at indices 3 to 4.
Final array: [2, 3, 7, 7, 8]
Input: arr[] = [4, 5, 7, 9], opr[][] = [[1, 3, 1], [2, 3, -2]]
Ouput: [4, 6, 6, 8]
Explanation: After performing all the operations the final array look like [4, 6, 6, 8]
[Naive Approach] Using loops for each queries
For every operation (l, r, x), iterate from index l to r and add x to each element in that range. After all operations have been applied, traverse the array once to print the final result.
C++
#include <iostream>
#include <vector>
using namespace std;
// Function to apply a single operation:
// add x to elements from index l to r
void update(vector<int> &arr, int l, int r, int x) {
for (int i = l; i <= r; i++) {
arr[i] += x;
}
}
// Function to apply all operations in order
vector<int> diffArray(vector<int>& arr,
vector<vector<int>>& opr) {
// Apply each operation [l, r, v] to the array
// Here l , r are in 0 based indexing
for (auto &v : opr) {
update(arr, v[0], v[1], v[2]);
}
return arr;
}
int main() {
vector<int> arr = {2, 3, 5, 6, 7};
vector<vector<int>> opr = {
{2, 4, 2},
{3, 4, -1}
};
vector<int> res = diffArray(arr, opr);
for (int num : arr) {
cout << num << " ";
}
cout << endl;
return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;
class GfG {
// Function to apply a single operation:
// add x to elements from index l to r
static void update(int[] arr, int l, int r, int x) {
for (int i = l; i <= r; i++) {
arr[i] += x;
}
}
// Function to apply all operations in order
static ArrayList<Integer> diffArray(int[] arr, int[][] opr) {
for (int[] op : opr) {
update(arr, op[0], op[1], op[2]);
}
ArrayList<Integer> result = new ArrayList<>();
for (int num : arr) {
result.add(num);
}
return result;
}
public static void main(String[] args) {
int[] arr = {2, 3, 5, 6, 7};
int[][] opr = {
{2, 4, 2},
{3, 4, -1}
};
ArrayList<Integer> res = diffArray(arr, opr);
for (int num : res) {
System.out.print(num + " ");
}
System.out.println();
}
}
Python
# Function to apply a single operation:
# add x to elements from index l to r
def update(arr, l, r, x):
for i in range(l, r + 1):
arr[i] += x
# Function to apply all operations in order
def diffArray(arr, opr):
# Apply each operation [l, r, v] to the array
# Here l , r are in 0 based indexing
for v in opr:
update(arr, v[0], v[1], v[2])
return arr
if __name__ == "__main__":
arr = [2, 3, 5, 6, 7]
opr = [
[2, 4, 2],
[3, 4, -1]
]
res = diffArray(arr, opr)
for num in arr:
print(num, end=' ')
print()
C#
using System;
using System.Collections.Generic;
class GfG {
// Function to apply a single operation:
// add x to elements from index l to r
static void update(int[] arr, int l, int r, int x) {
for (int i = l; i <= r; i++) {
arr[i] += x;
}
}
// Function to apply all operations and return List<int>
static List<int> diffArray(int[] arr, int[][] opr) {
foreach (int[] op in opr) {
update(arr, op[0], op[1], op[2]);
}
List<int> result = new List<int>(arr);
return result;
}
static void Main() {
int[] arr = {2, 3, 5, 6, 7};
int[][] opr = {
new int[] {2, 4, 2},
new int[] {3, 4, -1}
};
List<int> res = diffArray(arr, opr);
foreach (int num in res) {
Console.Write(num + " ");
}
Console.WriteLine();
}
}
JavaScript
// Function to apply a single operation:
// add x to elements from index l to r
function update(arr, l, r, x) {
for (let i = l; i <= r; i++) {
arr[i] += x;
}
}
// Function to apply all operations in order
function diffArray(arr, opr) {
// Apply each operation [l, r, v] to the array
// Here l , r are in 0 based indexing
for (let v of opr) {
update(arr, v[0], v[1], v[2]);
}
return arr;
}
// Driver Code
let arr = [2, 3, 5, 6, 7];
let opr = [
[2, 4, 2],
[3, 4, -1]
];
let res = diffArray(arr, opr);
console.log(arr.join(" "));
Time Complexity: O(n × q), as each of the q operations may update up to n elements.
Auxiliary Space: O(1), since no extra space is used apart from a few variables.
[Better Approach] Using Difference Array
Instead of updating each element in the range for every operation, initialize a new array (same size as input) filled with zeros.
for each operation [l, r, v], do:
- if (r + 1 < n) diff[r + 1] -= v
This marks the range updates in constant time.
Finally, compute the prefix sum of the diff[] array and add it to the original array to get the final result.
Why it works:
- Instead of updating every element between
l
and r
for each operation (which can be slow), we just mark where the increase starts and where it ends. - Imagine this like placing a +v flag at index
l
(start adding v
), and a -v flag at index r + 1
(stop adding v
after index r
). You’re just saying: “Start adding v
here, and stop adding v
there.” - After placing all these flags (from all operations), you take a prefix sum — going through the array from left to right and applying the net effect of all flags.
- This way, every element automatically receives all the right updates — without updating each one manually per operation.
C++
#include <iostream>
#include <vector>
using namespace std;
// Function to apply a single range update
// on the difference array
void update(vector<int>& d, int l, int r, int x) {
// Adding v at index l
d[l] += x;
// Subtracting v at index r + 1 ensures the addition
// stops at index r when prefix sums are applied
d[r + 1] -= x;
}
// Function to initialize difference array, handle all
// queries, and apply prefix sum
vector<int> diffArray(vector<int>& arr,
vector<vector<int>>& opr) {
int n = arr.size();
vector<int> d(n + 1, 0);
// Process each operation [l, r, v]
for (auto& query : opr) {
int l = query[0];
int r = query[1];
int v = query[2];
update(d, l, r, v);
}
// Apply prefix sum to get final result
for (int i = 0; i < n; i++) {
if (i > 0) d[i] += d[i - 1];
arr[i] += d[i];
}
return arr;
}
int main() {
vector<int> arr = {2, 3, 5, 6, 7};
vector<vector<int>> opr = {
{2, 4, 2},
{3, 4, -1}
};
vector<int> res = diffArray(arr, opr);
for (int i = 0; i < res.size(); i++) {
cout << res[i] << " ";
}
cout << endl;
return 0;
}
Java
import java.util.ArrayList;
import java.util.List;
class GfG {
// Function to apply a single range update
// on the difference array
static void update(int[] d, int l, int r, int x) {
d[l] += x;
if (r + 1 < d.length) {
d[r + 1] -= x;
}
}
// Function to process operations
static ArrayList<Integer> diffArray(int[] arr, int[][] opr) {
int n = arr.length;
int[] d = new int[n + 1];
// Apply all operations to the difference array
for (int[] query : opr) {
int l = query[0];
int r = query[1];
int v = query[2];
update(d, l, r, v);
}
// Apply prefix sum and construct result
for (int i = 0; i < n; i++) {
if (i > 0) d[i] += d[i - 1];
arr[i] += d[i];
}
// Convert array to ArrayList and return
ArrayList<Integer> result = new ArrayList<>();
for (int num : arr) {
result.add(num);
}
return result;
}
public static void main(String[] args) {
int[] arr = {2, 3, 5, 6, 7};
int[][] opr = {
{2, 4, 2},
{3, 4, -1}
};
ArrayList<Integer> res = diffArray(arr, opr);
for (int num : res) {
System.out.print(num + " ");
}
System.out.println();
}
}
Python
# Function to apply a single range update
# on the difference array
def update(d, l, r, x):
# Adding v at index l
d[l] += x
# Subtracting v at index r + 1 ensures the addition
# stops at index r when prefix sums are applied
if r + 1 < len(d):
d[r + 1] -= x
# Function to initialize difference array, handle
# all queries, and apply prefix sum
def diffArray(arr, opr):
n = len(arr)
d = [0] * (n + 1)
# Process each operation [l, r, v]
for l, r, v in opr:
update(d, l, r, v)
# Apply prefix sum to get final result
for i in range(n):
if i > 0:
d[i] += d[i - 1]
arr[i] += d[i]
return arr
if __name__ == "__main__":
arr = [2, 3, 5, 6, 7]
opr = [
[2, 4, 2],
[3, 4, -1]
]
res = diffArray(arr, opr)
for num in res:
print(num, end=" ")
print()
C#
using System;
using System.Collections.Generic;
class GfG {
// Function to apply a single range update
// on the difference array
static void update(int[] d, int l, int r, int x) {
d[l] += x;
if (r + 1 < d.Length) {
d[r + 1] -= x;
}
}
// Function to handle all queries
static List<int> diffArray(int[] arr, int[][] opr) {
int n = arr.Length;
int[] d = new int[n + 1];
// Apply all operations using difference array
foreach (var query in opr) {
int l = query[0];
int r = query[1];
int v = query[2];
update(d, l, r, v);
}
// Build the final array using prefix sum
for (int i = 0; i < n; i++) {
if (i > 0) d[i] += d[i - 1];
arr[i] += d[i];
}
// Convert array to List<int> and return
List<int> result = new List<int>();
foreach (int num in arr) {
result.Add(num);
}
return result;
}
static void Main() {
int[] arr = {2, 3, 5, 6, 7};
int[][] opr = new int[][] {
new int[] {2, 4, 2},
new int[] {3, 4, -1}
};
List<int> res = diffArray(arr, opr);
foreach (int num in res) {
Console.Write(num + " ");
}
Console.WriteLine();
}
}
JavaScript
// Function to apply a single range update on
// the difference array
function update(d, l, r, x) {
// Adding v at index l
d[l] += x;
// Subtracting v at index r + 1 ensures the addition
// stops at index r when prefix sums are applied
if (r + 1 < d.length) {
d[r + 1] -= x;
}
}
// Function to initialize difference array, handle
// all queries, and apply prefix sum
function diffArray(arr, opr) {
let n = arr.length;
let d = new Array(n + 1).fill(0);
// Process each operation [l, r, v]
for (let [l, r, v] of opr) {
update(d, l, r, v);
}
// Apply prefix sum to get final result
for (let i = 0; i < n; i++) {
if (i > 0) d[i] += d[i - 1];
arr[i] += d[i];
}
return arr;
}
// Driver code
let arr = [2, 3, 5, 6, 7];
let opr = [
[2, 4, 2],
[3, 4, -1]
];
let res = diffArray(arr, opr);
console.log(res.join(" "));
Time Complexity: O(n + q), O(q) for updates and O(n) for prefix sum.
Auxiliary Space: O(n), for the difference array used to store range updates.
[Efficient Approach] In-Place Difference Array for Range Updates
The in-place difference array approach works by transforming the original array into a difference array, where each element represents the change from its previous element. This allows range updates to be applied in constant time by modifying just two positions — the start and end+1 of the range. Later, taking a prefix sum reconstructs the final updated array. This works because the prefix sum of a difference array always yields the original or updated values efficiently.
Step by step approach:
- Convert original array to difference form:
- Update each element from right to left as arr[i] = arr[i] - arr[i - 1] for i > 0. This transforms the array into its own difference array.
- Apply each operation [l, r, v]:
- Do arr[l] += v to start adding v from index l.
- Do arr[r + 1] -= v to stop adding v after index r (if r + 1 < n).
- Restore the final array by traversing the array from left to right, adding arr[i - 1] to arr[i] to compute the prefix sum and recover the final updated values.
- The modified array now holds the result after applying all range updates efficiently in-place.
C++
#include <iostream>
#include <vector>
using namespace std;
vector<int> diffArray(vector<int>& arr, vector<vector<int>>& opr) {
int n = arr.size();
// Convert arr to in-place difference array
for (int i = n - 1; i > 0; i--) {
arr[i] -= arr[i - 1];
}
// Apply each operation directly on the original array
// Each operation is of the form [l, r, v]
for (auto& q : opr) {
int l = q[0], r = q[1], v = q[2];
// Adding v at index l
arr[l] += v;
// Subtracting v at index r + 1 ensures the addition
// stops at index r when prefix sums are applied
if (r + 1 < n) arr[r + 1] -= v;
}
// Take prefix sum to get the final updated array
for (int i = 1; i < n; i++) {
arr[i] += arr[i - 1];
}
return arr;
}
int main() {
vector<int> arr = {2, 3, 5, 6, 7};
vector<vector<int>> opr = {
{2, 4, 2},
{3, 4, -1}
};
vector<int> res = diffArray(arr, opr);
for (int num : res) {
cout << num << " ";
}
cout << endl;
return 0;
}
Java
import java.util.ArrayList;
import java.util.List;
class GfG {
public static ArrayList<Integer> diffArray(int[] arr, int[][] opr) {
int n = arr.length;
// Convert arr to in-place difference array
for (int i = n - 1; i > 0; i--) {
arr[i] -= arr[i - 1];
}
// Apply each operation [l, r, v]
for (int[] q : opr) {
int l = q[0], r = q[1], v = q[2];
arr[l] += v;
if (r + 1 < n) arr[r + 1] -= v;
}
// Take prefix sum to get final array
for (int i = 1; i < n; i++) {
arr[i] += arr[i - 1];
}
// Convert array to ArrayList
ArrayList<Integer> result = new ArrayList<>();
for (int num : arr) {
result.add(num);
}
return result;
}
public static void main(String[] args) {
int[] arr = {2, 3, 5, 6, 7};
int[][] opr = {
{2, 4, 2},
{3, 4, -1}
};
ArrayList<Integer> res = diffArray(arr, opr);
for (int num : res) {
System.out.print(num + " ");
}
System.out.println();
}
}
Python
def diffArray(arr, opr):
n = len(arr)
# Convert arr to in-place difference array
for i in range(n - 1, 0, -1):
arr[i] -= arr[i - 1]
# Apply each operation directly on the original array
# Each operation is of the form [l, r, v]
for l, r, v in opr:
# Adding v at index l
arr[l] += v
# Subtracting v at index r + 1 ensures the addition
# stops at index r when prefix sums are applied
if r + 1 < n:
arr[r + 1] -= v
# Take prefix sum to get the final updated array
for i in range(1, n):
arr[i] += arr[i - 1]
return arr
if __name__ == "__main__":
arr = [2, 3, 5, 6, 7]
opr = [
[2, 4, 2],
[3, 4, -1]
]
res = diffArray(arr, opr)
print(*res)
C#
using System;
using System.Collections.Generic;
class GfG {
public static List<int> diffArray(int[] arr, int[][] opr) {
int n = arr.Length;
// Convert arr to in-place difference array
for (int i = n - 1; i > 0; i--) {
arr[i] -= arr[i - 1];
}
// Apply each operation [l, r, v]
foreach (var q in opr) {
int l = q[0], r = q[1], v = q[2];
arr[l] += v;
if (r + 1 < n) arr[r + 1] -= v;
}
// Take prefix sum to restore the final array
for (int i = 1; i < n; i++) {
arr[i] += arr[i - 1];
}
// Convert array to List<int>
List<int> result = new List<int>();
foreach (int num in arr) {
result.Add(num);
}
return result;
}
// Driver code
public static void Main() {
int[] arr = {2, 3, 5, 6, 7};
int[][] opr = {
new int[] {2, 4, 2},
new int[] {3, 4, -1}
};
List<int> res = diffArray(arr, opr);
foreach (int num in res) {
Console.Write(num + " ");
}
Console.WriteLine();
}
}
JavaScript
function diffArray(arr, opr) {
let n = arr.length;
// Convert arr to in-place difference array
for (let i = n - 1; i > 0; i--) {
arr[i] -= arr[i - 1];
}
// Apply each operation directly on the original array
// Each operation is of the form [l, r, v]
for (let [l, r, v] of opr) {
// Adding v at index l
arr[l] += v;
// Subtracting v at index r + 1 ensures the addition
// stops at index r when prefix sums are applied
if (r + 1 < n) {
arr[r + 1] -= v;
}
}
// Take prefix sum to get the final updated array
for (let i = 1; i < n; i++) {
arr[i] += arr[i - 1];
}
return arr;
}
// Driver code
let arr = [2, 3, 5, 6, 7];
let opr = [
[2, 4, 2],
[3, 4, -1]
];
let res = diffArray(arr, opr);
console.log(res.join(" "));
Time Complexity: O(n + q), O(q) for updates and O(n) for prefix sum.
Auxiliary Space: O(1), since no extra space is used apart from a few variables.
Similar Reads
PreComputation Technique on Arrays Precomputation refers to the process of pre-calculating and storing the results of certain computations or data structures(array in this case) in advance, in order to speed up the execution time of a program. This can be useful in situations where the same calculations are needed multiple times, as
15 min read
Queries for the product of first N factorials Given Q[] queries where each query consists of an integer N, the task is to find the product of first N factorials for each of the query. Since the result could be large, compute it modulo 109 + 7.Examples: Input: Q[] = {4, 5} Output: 288 34560 Query 1: 1! * 2! * 3! * 4! = 1 * 2 * 6 * 24 = 288 Query
7 min read
Range sum queries without updates Given an array arr of integers of size n. We need to compute the sum of elements from index i to index j. The queries consisting of i and j index values will be executed multiple times.Examples: Input : arr[] = {1, 2, 3, 4, 5} i = 1, j = 3 i = 2, j = 4Output : 9 12 Input : arr[] = {1, 2, 3, 4, 5} i
6 min read
Range Queries for Frequencies of array elements Given an array of n non-negative integers. The task is to find frequency of a particular element in the arbitrary range of array[]. The range is given as positions (not 0 based indexes) in array. There can be multiple queries of given type. Examples: Input : arr[] = {2, 8, 6, 9, 8, 6, 8, 2, 11}; lef
13 min read
Count Primes in Ranges Given a 2d array queries[][] of size n, where each query queries[i] contain 2 elements [l, r], your task is to find the count of number of primes in inclusive range [l, r]Examples: Input: queries[][] = [ [1, 10], [5, 10], [11, 20] ]Output: 4 2 4Explanation: For query 1, number of primes in range [1,
12 min read
Check in binary array the number represented by a subarray is odd or even Given an array such that all its terms is either 0 or 1.You need to tell the number represented by a subarray a[l..r] is odd or even Examples : Input : arr = {1, 1, 0, 1} l = 1, r = 3 Output : odd number represented by arr[l...r] is 101 which 5 in decimal form which is odd Input : arr = {1, 1, 1, 1}
4 min read
GCDs of given index ranges in an Array Given an array arr[] of size N and Q queries of type {qs, qe} where qs and qe denote the starting and ending index of the query, the task is to find the GCD of all the numbers in the range. Examples: Input: arr[] = {2, 3, 60, 90, 50};Index Ranges: {1, 3}, {2, 4}, {0, 2}Output: GCDs of given ranges a
14 min read
Mean of range in array Given an array arr[] of n integers and q queries represented by an array queries[][], where queries[i][0] = l and queries[i][1] = r. For each query, the task is to calculate the mean of elements in the range l to r and return its floor value. Examples: Input: arr[] = [3, 7, 2, 8, 5] queries[][] = [[
12 min read
Difference Array | Range update query in O(1) Given an array arr[] and a 2D array opr[][], where each row represents an operation in the form [l, r, v]. For each operation, add v to all elements from index l to r in arr. Return the updated array after applying all operations.Examples : Input: arr[] = [2, 3, 5, 6, 7], opr[][] = [[2, 4, 2], [3, 4
15+ min read
Range sum query using Sparse Table We have an array arr[]. We need to find the sum of all the elements in the range L and R where 0 <= L <= R <= n-1. Consider a situation when there are many range queries. Examples: Input : 3 7 2 5 8 9 query(0, 5) query(3, 5) query(2, 4) Output : 34 22 15Note : array is 0 based indexed and q
8 min read