1. Raw Array Storage
Intuition
Store the input array in standard 1-based indexed memory:
- update(index, delta): Modify the single element nums[index] += delta in O(1).
- query(index): Loop from 1 to index accumulating sum in O(n).
- queryRange(left, right): Loop from left to right summing elements in O(n).
Processing Q queries on an array of length N takes O(Q \cdot N) worst case.
When to apply: When queries are extremely rare compared to updates.
Algorithm
- Step 1: Store elements in an array nums of size n + 1.
- Step 2: On update(index, delta), nums[index] += delta in O(1).
- Step 3: On query(index), loop i from 1 to index adding nums[i].
- Step 4: On queryRange(left, right), loop i from left to right adding nums[i].
#include <iostream>#include <vector> class FenwickBrute { std::vector<int> nums;public: FenwickBrute(const std::vector<int>& arr) { nums.resize(arr.size() + 1, 0); for (size_t i = 0; i < arr.size(); ++i) nums[i + 1] = arr[i]; } void update(int idx, int delta) { nums[idx] += delta; } long long query(int idx) { long long sum = 0; for (int i = 1; i <= idx; ++i) sum += nums[i]; return sum; } long long queryRange(int l, int r) { long long sum = 0; for (int i = l; i <= r; ++i) sum += nums[i]; return sum; }}; int main() { std::vector<int> nums = {2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9}; FenwickBrute ft(nums); std::cout << ft.query(5) << std::endl; ft.update(3, 6); std::cout << ft.query(5) << std::endl; std::cout << ft.queryRange(2, 6) << std::endl; return 0;}Time & Space Complexity
- Time complexity:
O(1) for update, O(n) for query and queryRange - Space complexity:
O(n) auxiliary space