My naive Fenwick solution (value space) failed with the last test case in which there's INT_MIN\INT_MAX..
So I learnt a smarter thought on Fenwick:
https://leetcode.com/discuss/79907/summary-divide-conquer-based-binary-indexed-based-solutions
It is in Index Space - which saves quite a bit of space. The basic idea
1. In the Fenwitk tree, we only store indices - but these indices mean i-th large in the input value space. That means we need a sort on all target values.
2. In Fenwick tree, index 0 is the root and we don't use it !
I simply translated the Java code in the above link to C++:
class Solution { // Fenwick tree ops void update(vector<int>& bit, int index, int value) { while (index < bit.size()) { bit[index] += value; index += index & -index; } } int query(vector<int>& bit, int index) { int sum = 0; while (index > 0) { sum += bit[index]; index -= index & -index; } return sum; } // int getIndex(vector<long long>& nums, long long val) { int r = lower_bound(nums.begin(), nums.end(), val) - nums.begin(); return r; } public: int countRangeSum(vector<int>& nums, int lower, int upper) { int n = nums.size(); if(!n) return 0; vector<long long> sum(nums.size() + 1); vector<long long> cand(3*sum.size() + 1); // Get pre-sum and cand number array ready cand.push_back(sum[0]); cand.push_back(lower + sum[0] - 1); cand.push_back(upper + sum[0]); for (int i = 1; i < sum.size(); i++) { sum[i] = sum[i - 1] + nums[i - 1]; cand.push_back(sum[i]); cand.push_back(lower + sum[i] - 1); cand.push_back(upper + sum[i]); } // in Fenwick tree index 0 is the root, we don't use it cand.push_back(LLONG_MIN); sort(cand.begin(), cand.end()); // Fenwick vector<int> fen(cand.size()); // Value-Sorted index based instead of value based for(int i = 0; i < sum.size(); i ++) { update(fen, getIndex(cand, sum[i]), 1); } int count = 0; for(int i = 1; i < sum.size(); i ++) { // remove last checked elem update(fen, getIndex(cand, sum[i - 1]), -1); count += query(fen, getIndex(cand, upper + sum[i - 1])); count -= query(fen, getIndex(cand, lower + sum[i - 1] - 1)); } return count; } };
And an alternative solution is to use MergeSort to count, also interesting:
https://leetcode.com/discuss/79154/short-%26-simple-o-n-log-n