localnews.ie

**Answer**

The problem is a classic “maximum‑weight independent set” on a graph that is a disjoint union of paths. For a single path the dynamic programming recurrence is

\[ \begin{aligned} dp[i] &= \max\bigl(dp[i-1],\; dp[i-2] + w_i\bigr),\\ dp[0] &= 0,\qquad dp[1] = w_1 . \end{aligned} \]

The recurrence is linear, so it can be written as a matrix multiplication

\[ \begin{pmatrix}dp[i]\\dp[i-1]\\1\end{pmatrix} = \begin{pmatrix} 0 & 1 & w_i\\ 1 & 0 & 0\\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix}dp[i-1]\\dp[i-2]\\1\end{pmatrix}. \]

Thus the whole path can be processed by multiplying the matrices \(M_i\) in order. Because the matrices are \(3\times3\) we can multiply two of them in \(O(1)\) time, and we can combine a whole block of consecutive matrices by binary exponentiation in \(O(\log n)\) time. If we pre‑compute the product of every block of length \(B\) (for example \(B=256\)), then a query that asks for the maximum weight on a segment \([l,r]\) can be answered in

\[ O\!\left(\frac{r-l+1}{B}\right)+O(\log B) \]

time, which is sub‑linear for large segments. The preprocessing takes \(O(n)\) time and \(O(n/B)\) space.

If the graph is not a single path but a forest of paths (the “no‑two‑adjacent‑vertices” condition is applied separately on each connected component), the same idea works component‑wise; we just store the matrix product for each component and answer queries by combining the relevant components.

---

**Why this works**

* The recurrence is linear, so it can be represented by a matrix. * Matrix multiplication is associative, so we can combine many consecutive steps into one product. * By pre‑computing products of blocks we reduce the number of multiplications needed for a query. * The resulting algorithm is faster than the naïve \(O(n)\) scan for long queries and uses only linear space.

---

**When it might not be the best choice**

* If the graph is not a path (e.g. contains cycles or a general tree), the recurrence changes and the matrix‑product trick no longer applies directly. * If the queries are very short (few vertices), the overhead of matrix multiplication may dominate the benefit. * If the weights are not integers or the matrix entries become huge, numerical stability or overflow can become an issue.

In those cases one would need a different data structure (e.g. a segment tree that stores the four possible DP states for each interval) or a different algorithm entirely.

Summary written by localnews.ie from the original source coverage. Click through for the full report.

Something thin or off here?Flag this story for a closer look.