classBIT { private: staticconstint MAXN = 100010; int bit[MAXN];
public: BIT() { memset(bit, 0, sizeof bit); }
intlowbit(int x){ return x&(-x); }
voidadd(int i, int x){ while (i < MAXN) { bit[i] += x; i += lowbit(i); } }
voidsub(int i, int x){ while (i < MAXN) { bit[i] -= x; i += lowbit(i); } }
intsum(int i){ int s = 0; while (i > 0) { s += bit[i]; i -= lowbit(i); } return s; } };
classID { private: unordered_map<ll, int> mp; set<ll> st; int idx;
public: ID() { mp.clear(); st.clear(); idx = 1; }
voidaddNum(ll x){ st.insert(x); }
voidproj(){ for (ll x: st) { mp[x] = idx++; } }
intgetID(ll x){ return mp[x]; } };
classSolution { public: intcountRangeSum(vector<int>& nums, int lower, int upper){ int n = nums.size(); ll sum = 0, res = 0; ID id = ID(); BIT bit = BIT();
id.addNum(0); for (int i = 0; i < n; ++i) { sum += nums[i]; id.addNum(sum); id.addNum(sum-lower); id.addNum(sum-upper); } id.proj();
bit.add(id.getID(0), 1); sum = 0; for (int i = 0; i < n; ++i) { sum += nums[i]; int lb = id.getID(sum-upper), rb = id.getID(sum-lower); res += bit.sum(rb) - bit.sum(lb-1); bit.add(id.getID(sum), 1); } return res; } };