Prefix Sums - C Plus Plus
- Which prefix-sum expression correctly evaluates this circular query? Answer: When working with circular prefix-sum queries, you need to think in two segments: the "tail" from your start index to the end of the array, and the "head" from index 0 to your stop index (inclusive). The exclusive prefix array is defined so that is the sum of all elements before index , meaning the sum of elements from index to is . Here, the query starts at index 3, runs through the end (index 4), wraps around, and stops at index 1 inclusive. That means you need two pieces: elements at indices 3–4 (the tail), and elements at indices 0–1 (the head). The tail sum is , covering and . The head sum covering indices 0 through 1 inclusive is , covering and . Total: ... wait — , and since , you can simplify to just . So the full expression is ... that's ... actually re-checking: , ? No — ? The array gives , so . Head sum covers only index 0 (... no, and ). So represents indices 0 and 1 combined. Thus , which is answer C. Choice A uses (only index 3) and , missing index 4 entirely. Choice B uses , capturing only index 0 and missing index 1. Choice D uses (only index 4), dropping index 3. Your strategy: always identify the two boundary indices explicitly — the tail runs from start to , and the head runs from to the stop index's exclusive upper bound. Drawing the circular array physically before writing expressions saves costly off-by-one mistakes.
- What does the program print, and which elements does the expression actually sum? Answer: It prints , summing indices through . Whenever you work with prefix sums in C++, you need to carefully track what the prefix array stores and what the subtraction formula actually computes. The standard formula
p[r] - p[l]gives you the sum of elements from indexlthrough indexr - 1in the original array — not throughrinclusive. Here's how the prefix array builds up:p[0] = 0,p[1] = 3,p[2] = 9,p[3] = 7,p[4] = 12,p[5] = 16. Withl = 1andr = 4, the expression computesp[4] - p[1] = 12 - 3 = 9. This coversa[1] + a[2] + a[3]= — indices 1 through 3, not 1 through 4. So A is correct. Choice B claims the result is summing indices 1–4. To actually include index 4 (value 4), you'd needp[5] - p[1] = 16 - 3 = 13, which requiresr = 5, notr = 4. Choice C suggests , which equalsp[4]alone — that's the prefix sum from index 0 through 3, achieved byp[4] - p[0], not by this expression. Choice D suggests , which isp[5], the full array sum — not what this code computes. The key trap here is the off-by-one error in the query:p[r] - p[l]sums elements from indexltor - 1. To sum indiceslthroughrinclusive, you must usep[r + 1] - p[l]. Always verify your prefix-sum boundaries by writing out a small example like this one before coding. - Which expression correctly computes the sum of the elements from index through index , inclusive, and what value does it produce? Answer: Whenever you see a prefix sum question, your first instinct should be to recall the core formula: the sum of elements from index to index (inclusive) equals . The "exclusive" prefix array shifts everything by one — stores the sum of all elements before index , not including it. Here, you want the sum of through , which means and . Plugging into the formula: . You can verify by hand: . That confirms A is correct. Choice B uses , which only captures elements up to index , missing . This is the classic off-by-one trap — forgetting to use as the upper index. Choice C uses , which shifts the left boundary incorrectly to exclude and start from instead. Choice D compounds both errors: cuts off the right side early and starts from the wrong left index. As a quick study tip, always write out the formula explicitly before substituting. The most common mistake on prefix sum problems is forgetting the on the right bound — a single index slip changes your answer entirely.
- Which return statement correctly handles every valid pair of indices, including ranges that begin at index ? Answer:
return p[r] - (l == 0 ? 0 : p[l - 1]);Prefix sum arrays are a classic optimization technique — understanding how to query them correctly is the key skill being tested here. When you build an inclusive prefix array where , the sum of any subarray from index to is recovered by subtracting whatever was accumulated before index . The correct formula is , which gives you (sum through ) minus (sum through ), leaving exactly the range you want. The problem is that when , is undefined — an out-of-bounds access. Answer B handles this elegantly with a ternary:p[r] - (l == 0 ? 0 : p[l - 1]). When , it subtracts (nothing came before), and otherwise subtracts correctly. A returns , which subtracts itself rather than , so it excludes from the result — always one element short. C uses instead of , which excludes from the sum entirely, making the range wrong on the right side. D returns when , but , so it incorrectly subtracts even though it should be included in the range. As a study tip, whenever you work with prefix sums, always ask: *what happens at the boundary where ?* That edge case is the most common source of bugs — and exam questions. - Which expression correctly computes the query sum without accessing an invalid prefix index when
lis zero?Answer:p[r - 1] - (l == 0 ? 0 : p[l - 1])Prefix sum questions require careful attention to two things simultaneously: index boundaries and interval conventions. When a query is half-open[l, r), it includes indexlbut excludes indexr, meaning the last included element isa[r-1], so the rightmost prefix you need isp[r-1], notp[r]. The correct formula for a half-open query is: This is exactly B. Whenl > 0, you subtractp[l-1]to remove elements before indexl. Whenl == 0, there's nothing to subtract, so you use0. No invalid index is ever accessed. A is wrong because it usesp[r]as the right endpoint. Since the query excludes indexr,a[r]should not be included. This off-by-one error adds one extra element to the sum. C usesp[r-1]correctly for the right side, but thel == 0branch returnsp[0]instead of0. Subtractingp[0]removesa[0]from the sum, but whenl == 0,a[0]should be included — so this undercounts. D combines both errors: it usesp[r](wrong right boundary, includes one extra element) and whenl == 0it subtractsp[0](incorrectly removesa[0]). As a strategy, always ask two separate questions: Where does the range end? (adjust for open/closed) and What do I subtract on the left? (guard against negative indexing). Treating them independently prevents combining errors the way A, C, and D do. - Which range has a sum of exactly ? Answer: Indices through , inclusive When working with prefix sum arrays, the key formula to internalize is: the sum of elements from index to index (inclusive) equals , where is the exclusive prefix array. Here, "exclusive" means and each entry represents the sum of all elements before index , not including it. Given , let's verify option C — indices 2 through 5 inclusive. Applying the formula: . That's exactly the target, confirming C is correct. Now let's see why the others fail. A asks for indices 0 through 3: , not 10. B covers indices 1 through 4: , also not 10. D targets indices 3 through 5: , still not 10. Each wrong answer likely traps students who either use instead of (off-by-one error) or subtract the wrong endpoint. The most common mistake here is the off-by-one: forgetting to use for the right boundary. A reliable tip — write the formula on scratch paper before evaluating any range, so the index shift becomes a deliberate step rather than an afterthought.
- What is the largest valid value of
rfor which the query sum is exactly ?Answer: , becausep[5] - p[1]equals , matching the target When working with prefix arrays, the key formula for a range query sum from index to (inclusive) is . Here, the query starts at , so you're always computing , where . The question asks for the largest where this sum equals exactly . Working through each candidate: . That's an exact match at , making D the correct answer. The passage explicitly notes that prefix values aren't guaranteed to increase, which means you can't assume that once you pass a valid answer, no later one exists — you must check all possibilities before concluding you've found the largest. Choice A claims , which is , not , and "closest below" is irrelevant — the question requires an exact match. Choice B states , computing , which again misses the target of and confusingly claims it "matches." Choice C computes , not , and "closest above" doesn't satisfy an exact-match requirement. A helpful strategy: always verify every candidate when the question asks for a largest or smallest valid index — non-monotonic prefix arrays mean early mismatches don't rule out later exact matches. Compute each one explicitly rather than stopping at the first hit. - What do the calls for the ranges
[3, 3)and[0, n)return, respectively?Answer: Zero, then the sum of every array element Prefix sum arrays are a classic technique for answering range queries in constant time. When you see a half-open range[l, r), remember that it includes indexlbut excludes indexr. The formulap[r] - p[l]exploits this directly, wherep[i]stores the cumulative sum of all elements from index0up to (but not including) indexi. For the range[3, 3), you computep[3] - p[3], which equals exactly . An empty range — where left and right endpoints are equal — always yields zero because no elements are included. For the range[0, n), you computep[n] - p[0]. Sincep[n]holds the total sum of all elements andp[0]is (no elements precede index 0), the result is the complete array sum. So A is correct: an empty range returns zero, and[0, n)returns every element's sum. B is wrong because[3, 3)contains no elements — it doesn't return the element at index 3. You'd need the range[3, 4)for that single element. C is wrong because[0, n)uses a half-open convention that already excludes indexn, notn-1— the subtractionp[n] - p[0]captures all elements from0throughn-1, which is the full array. D is wrong because both inputs satisfy the validity constraint0 <= l <= r <= n, so no undefined behavior occurs. A useful tip: always check whetherl == rwhen reasoning about prefix sums — that edge case is a favorite test question because it cleanly exposes whether you understand the half-open interval convention. - Which is the smallest direct repair to
pthat makes all subsequent range-sum queries correct?Answer: Add top[3]throughp[n]. When working with prefix arrays, always ask yourself: *which entries inpactually depend on the element that changed?* The exclusive prefix array is defined as , meaningp[k]includesa[j]only when . So ifa[2]increases by , every prefix entry that includesa[2]in its sum must be updated. The first entry that includesa[2]isp[3], because . Every subsequent entryp[4],p[5], ...,p[n]also includesa[2], so all of them are off by . Adding to each ofp[3]throughp[n]— answer A — is exactly the minimal, complete repair. Answer B is wrong because it stops atp[n-1]and missesp[n], leaving the last prefix entry still incorrect. It also incorrectly starts atp[2], but doesn't includea[2]at all, so updating it corrupts a value that was fine. Answer C updates onlyp[3], ignoring thatp[4]throughp[n]are equally stale. A single-entry patch leaves every longer range-sum broken. Answer D adds starting fromp[0], but through don't containa[2]; touching them introduces new errors rather than fixing existing ones. Study tip: For any prefix-array update problem, identify the first index where the changed element appears ( for a change at index ) and propagate the delta *all the way throughp[n]* — missing either end is a classic trap. - Which implementation reliably prevents overflow in both prefix construction and range subtraction? Answer: Store prefixes in
long longand returnp[r + 1] - p[l]. Whenever you see a question about prefix sums, your first instinct should be to calculate the worst-case accumulated value before choosing a storage type. Here, you have up to values each up to , so the maximum possible prefix sum is . That already exceeds the 32-bit signedintmaximum of roughly , meaning overflow can occur during construction, not just at the query stage. Option D stores prefixes directly inlong long, which holds values up to roughly , comfortably covering . Both the prefix array construction and the range subtractionp[r + 1] - p[l]operate entirely inlong long, so overflow is impossible at every step. Option A fails because the overflow happens when you write into theintprefix array — casting the final difference tolong longafter the damage is already done doesn't help. Option B has the same fundamental flaw: casting the return expression operates on already-corruptedintvalues, so you're just widening a broken result. Option C attempts to useunsigned int, which has a maximum of roughly — still less than , so overflow remains possible during construction. Additionally, unsigned subtraction wraps around rather than producing a negative result, which silently corrupts queries wherep[l] > p[r + 1]due to wrap. The takeaway: always compute the worst-case sum before choosing your data type, and ensure the type is wide enough at the point of storage, not just at the point of return.