classSolution{public:intcountRangeSum(vector<int>&nums,intlower,intupper){constintn=nums.size();intans=0;vector<long>prefix(n+1);for(inti=0;i<n;++i)prefix[i+1]=prefix[i]+nums[i];mergeSort(prefix,0,n,lower,upper,ans);returnans;}private:voidmergeSort(vector<long>&prefix,intl,intr,intlower,intupper,int&ans){if(l>=r)return;constintm=(l+r)/2;mergeSort(prefix,l,m,lower,upper,ans);mergeSort(prefix,m+1,r,lower,upper,ans);merge(prefix,l,m,r,lower,upper,ans);}voidmerge(vector<long>&prefix,intl,intm,intr,intlower,intupper,int&ans){intlo=m+1;// 1st index s.t. prefix[lo] - prefix[i] >= lowerinthi=m+1;// 1st index s.t. prefix[hi] - prefix[i] > upper// For each index i in range [l, m], add hi - lo to ansfor(inti=l;i<=m;++i){while(lo<=r&&prefix[lo]-prefix[i]<lower)++lo;while(hi<=r&&prefix[hi]-prefix[i]<=upper)++hi;ans+=hi-lo;}vector<long>sorted(r-l+1);intk=0;// sorted's indexinti=l;// left's indexintj=m+1;// right's indexwhile(i<=m&&j<=r)if(prefix[i]<prefix[j])sorted[k++]=prefix[i++];elsesorted[k++]=prefix[j++];// Put possible remaining left part to the sorted arraywhile(i<=m)sorted[k++]=prefix[i++];// Put possible remaining right part to the sorted arraywhile(j<=r)sorted[k++]=prefix[j++];copy(begin(sorted),end(sorted),begin(prefix)+l);}};
classSolution{publicintcountRangeSum(int[]nums,intlower,intupper){finalintn=nums.length;long[]prefix=newlong[n+1];for(inti=0;i<n;++i)prefix[i+1]=(long)nums[i]+prefix[i];mergeSort(prefix,0,n,lower,upper);returnans;}privateintans=0;privatevoidmergeSort(long[]prefix,intl,intr,intlower,intupper){if(l>=r)return;finalintm=(l+r)/2;mergeSort(prefix,l,m,lower,upper);mergeSort(prefix,m+1,r,lower,upper);merge(prefix,l,m,r,lower,upper);}privatevoidmerge(long[]prefix,intl,intm,intr,intlower,intupper){intlo=m+1;// 1st index s.t. prefix[lo] - prefix[i] >= lowerinthi=m+1;// 1st index s.t. prefix[hi] - prefix[i] > upper// For each index i in range [l, m], add hi - lo to ansfor(inti=l;i<=m;++i){while(lo<=r&&prefix[lo]-prefix[i]<lower)++lo;while(hi<=r&&prefix[hi]-prefix[i]<=upper)++hi;ans+=hi-lo;}long[]sorted=newlong[r-l+1];intk=0;// sorted's indexinti=l;// left's indexintj=m+1;// right's indexwhile(i<=m&&j<=r)if(prefix[i]<prefix[j])sorted[k++]=prefix[i++];elsesorted[k++]=prefix[j++];// Put possible remaining left part to the sorted arraywhile(i<=m)sorted[k++]=prefix[i++];// Put possible remaining right part to the sorted arraywhile(j<=r)sorted[k++]=prefix[j++];System.arraycopy(sorted,0,prefix,l,sorted.length);}}
classSolution:defcountRangeSum(self,nums:List[int],lower:int,upper:int)->int:n=len(nums)self.ans=0prefix=[0]+list(itertools.accumulate(nums))self._mergeSort(prefix,0,n,lower,upper)returnself.ansdef_mergeSort(self,prefix:List[int],l:int,r:int,lower:int,upper:int)->None:ifl>=r:returnm=(l+r)//2self._mergeSort(prefix,l,m,lower,upper)self._mergeSort(prefix,m+1,r,lower,upper)self._merge(prefix,l,m,r,lower,upper)def_merge(self,prefix:List[int],l:int,m:int,r:int,lower:int,upper:int)->None:lo=m+1# 1st index s.t. prefix[lo] - prefix[i] >= lowerhi=m+1# 1st index s.t. prefix[hi] - prefix[i] > upper# For each index i in range [l, m], add hi - lo to ansforiinrange(l,m+1):whilelo<=randprefix[lo]-prefix[i]<lower:lo+=1whilehi<=randprefix[hi]-prefix[i]<=upper:hi+=1self.ans+=hi-losorted=[0]*(r-l+1)k=0# sorted's indexi=l# left's indexj=m+1# right's indexwhilei<=mandj<=r:ifprefix[i]<prefix[j]:sorted[k]=prefix[i]k+=1i+=1else:sorted[k]=prefix[j]k+=1j+=1# Put possible remaining left part to the sorted arraywhilei<=m:sorted[k]=prefix[i]k+=1i+=1# Put possible remaining right part to the sorted arraywhilej<=r:sorted[k]=prefix[j]k+=1j+=1prefix[l:l+len(sorted)]=sorted