Difference Array
差分陣列
illumeow
Sample Problem
Given an 1-based interger array $A$ of size $n$, there are $m$ operations. Each operation consists two number $1 \le l \le r \le n$ and an integer $x$, which means that all elements in $[l, r]$ should add $x$. After all operations, output the final array.
Naïve Solution
Just use a for loop to apply each operation.
- Each operation need $r-l+1$, which is at most $n$ steps.
- There are $m$ operations.
- Hence, at most need $n \times m$ steps in total.
Too slow for large $n, m$ !
Observe each operation, we can see many elements are updated multiple times.
Figure 1: Example of three range-add operations overlapping on a 12-element array.
Difference Array
Define the difference array $D$ of array $A$ as follows: $$D[i] = A[i] - A[i-1], \quad \text{for } i=2,3,\ldots,n$$ where we define $D[1] = A[1]$ for convenience.
We can recover $A$ from $D$ by: $$A[i] = D[1] + D[2] + \cdots + D[i], \quad \text{for } i=1,2,\ldots,n$$ which is the prefix sum of $D$.
Example
A = [-7, 6, 9, 4, 3, -3, -6, -7]
D = [-7, 13, 3, -5, -1, 0, -3, -1]
Key Observation
To add $x$ to all elements in $[l, r]$ of $A$, we can do:
- Add $x$ to $D[l]$
- Subtract $x$ from $D[r+1]$ (if $r+1 \le n$)
Why? After recovering $A$ from $D$:
- For $i = 1,2,\ldots,l-1$, $A[i]$ is unchanged.
- For $i = l,l+1,\ldots,n$, $A[i]$ increases by $x$.
- For $i = r+1,r+2,\ldots,n$, $A[i]$ decreases by $x$.
- Hence, only $A[l], A[l+1], \ldots, A[r]$ increase by $x$.
Efficient Solution
- Initialize difference array $D$ using $A$.
- For each operation $(l, r, x)$:
- $D[l] \mathrel{+}= x$
- If $r+1 \le n$, $D[r+1] \mathrel{-}= x$
- Recover array $A$ from $D$ using prefix sums.
- Initializing $D$ takes $n$ steps.
- Each operation takes at most $2$ steps, so that is at most $2m$ steps.
- Recovering $A$ takes $n$ steps.
- In total, $2n + 2m$ steps! Much faster than $n \times m$!
Learn More!
- 2D difference array
- Binary Indexed Tree / Fenwick Tree
deck
By illumeow
deck
- 27