@@ -109,32 +109,220 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3748.Co
109109
110110<!-- solution:start -->
111111
112- ### 方法一
112+ ### 方法一: 分段计数
113+
114+ 根据题目描述,稳定子数组的定义是不存在逆序对的子数组,即子数组中的元素是非降序排列的。因此,我们可以将数组划分为若干个非降序的段,用一个数组 $\text{seg}$ 来记录每个段的起始位置。同时,我们还需要一个前缀和数组 $\text{text{s}}$ 来记录每个段内稳定子数组的数量。
115+
116+ 然后,对于每个查询 $[ l, r] $,可能存在 $3$ 种情况:
117+
118+ 1 . 查询区间 $[ l, r] $ 完全包含在某个段内,此时稳定子数组的数量可以直接通过公式计算得到,数量为 $\frac{(k + 1) \cdot k}{2}$,其中 $k = r - l + 1$。
119+ 2 . 查询区间 $[ l, r] $ 跨越了多个段,此时我们需要分别计算左侧不完整段、右侧不完整段和中间完整段的稳定子数组数量,然后将它们相加得到最终结果。
120+
121+ 时间复杂度为 $O((n + q) \log n)$,其中 $n$ 是数组的长度,$q$ 是查询的数量。空间复杂度为 $O(n)$。
113122
114123<!-- tabs:start -->
115124
116125#### Python3
117126
118127``` python
119-
128+ class Solution :
129+ def countStableSubarrays (
130+ self , nums : List[int ], queries : List[List[int ]]
131+ ) -> List[int ]:
132+ s = [0 ]
133+ l, n = 0 , len (nums)
134+ seg = []
135+ for r, x in enumerate (nums):
136+ if r == n - 1 or x > nums[r + 1 ]:
137+ seg.append(l)
138+ k = r - l + 1
139+ s.append(s[- 1 ] + (1 + k) * k // 2 )
140+ l = r + 1
141+ ans = []
142+ for l, r in queries:
143+ i = bisect_right(seg, l)
144+ j = bisect_right(seg, r) - 1
145+ if i > j:
146+ k = r - l + 1
147+ ans.append((1 + k) * k // 2 )
148+ else :
149+ a = seg[i] - l
150+ b = r - seg[j] + 1
151+ ans.append((1 + a) * a // 2 + s[j] - s[i] + (1 + b) * b // 2 )
152+ return ans
120153```
121154
122155#### Java
123156
124157``` java
125-
158+ class Solution {
159+ public long [] countStableSubarrays (int [] nums , int [][] queries ) {
160+ List<Integer > seg = new ArrayList<> ();
161+ List<Long > s = new ArrayList<> ();
162+ s. add(0L );
163+
164+ int l = 0 ;
165+ int n = nums. length;
166+ for (int r = 0 ; r < n; r++ ) {
167+ if (r == n - 1 || nums[r] > nums[r + 1 ]) {
168+ seg. add(l);
169+ int k = r - l + 1 ;
170+ s. add(s. getLast() + (long ) k * (k + 1 ) / 2 );
171+ l = r + 1 ;
172+ }
173+ }
174+
175+ long [] ans = new long [queries. length];
176+ for (int q = 0 ; q < queries. length; q++ ) {
177+ int left = queries[q][0 ];
178+ int right = queries[q][1 ];
179+
180+ int i = upperBound(seg, left);
181+ int j = upperBound(seg, right) - 1 ;
182+
183+ if (i > j) {
184+ int k = right - left + 1 ;
185+ ans[q] = (long ) k * (k + 1 ) / 2 ;
186+ } else {
187+ int a = seg. get(i) - left;
188+ int b = right - seg. get(j) + 1 ;
189+ ans[q] = (long ) a * (a + 1 ) / 2 + s. get(j) - s. get(i) + (long ) b * (b + 1 ) / 2 ;
190+ }
191+ }
192+ return ans;
193+ }
194+
195+ private int upperBound (List<Integer > list , int target ) {
196+ int l = 0 , r = list. size();
197+ while (l < r) {
198+ int mid = (l + r) >> 1 ;
199+ if (list. get(mid) > target) {
200+ r = mid;
201+ } else {
202+ l = mid + 1 ;
203+ }
204+ }
205+ return l;
206+ }
207+ }
126208```
127209
128210#### C++
129211
130212``` cpp
131-
213+ class Solution {
214+ public:
215+ vector<long long > countStableSubarrays(vector<int >& nums, vector<vector<int >>& queries) {
216+ int n = nums.size();
217+ vector<int > seg;
218+ vector<long long > s = {0};
219+
220+ int l = 0;
221+ for (int r = 0; r < n; ++r) {
222+ if (r == n - 1 || nums[r] > nums[r + 1]) {
223+ seg.push_back(l);
224+ long long k = r - l + 1;
225+ s.push_back(s.back() + k * (k + 1) / 2);
226+ l = r + 1;
227+ }
228+ }
229+
230+ vector<long long > ans;
231+ for (auto & q : queries) {
232+ int left = q[0], right = q[1];
233+
234+ int i = upper_bound(seg.begin(), seg.end(), left) - seg.begin();
235+ int j = upper_bound(seg.begin(), seg.end(), right) - seg.begin() - 1;
236+
237+ if (i > j) {
238+ long long k = right - left + 1;
239+ ans.push_back(k * (k + 1) / 2);
240+ } else {
241+ long long a = seg[i] - left;
242+ long long b = right - seg[j] + 1;
243+ ans.push_back(a * (a + 1) / 2 + s[j] - s[i] + b * (b + 1) / 2);
244+ }
245+ }
246+
247+ return ans;
248+ }
249+ };
132250```
133251
134252#### Go
135253
136254``` go
255+ func countStableSubarrays (nums []int , queries [][]int ) []int64 {
256+ n := len (nums)
257+ seg := []int {}
258+ s := []int64 {0 }
259+
260+ l := 0
261+ for r := 0 ; r < n; r++ {
262+ if r == n-1 || nums[r] > nums[r+1 ] {
263+ seg = append (seg, l)
264+ k := int64 (r - l + 1 )
265+ s = append (s, s[len (s)-1 ]+k*(k+1 )/2 )
266+ l = r + 1
267+ }
268+ }
269+
270+ ans := make ([]int64 , len (queries))
271+ for idx , q := range queries {
272+ left , right := q[0 ], q[1 ]
273+
274+ i := sort.SearchInts (seg, left+1 )
275+ j := sort.SearchInts (seg, right+1 ) - 1
276+
277+ if i > j {
278+ k := int64 (right - left + 1 )
279+ ans[idx] = k * (k + 1 ) / 2
280+ } else {
281+ a := int64 (seg[i] - left)
282+ b := int64 (right - seg[j] + 1 )
283+ ans[idx] = a*(a+1 )/2 + s[j] - s[i] + b*(b+1 )/2
284+ }
285+ }
286+
287+ return ans
288+ }
289+ ```
137290
291+ #### TypeScript
292+
293+ ``` ts
294+ function countStableSubarrays(nums : number [], queries : number [][]): number [] {
295+ const n = nums .length ;
296+ const seg: number [] = [];
297+ const s: number [] = [0 ];
298+
299+ let l = 0 ;
300+ for (let r = 0 ; r < n ; r ++ ) {
301+ if (r === n - 1 || nums [r ] > nums [r + 1 ]) {
302+ seg .push (l );
303+ const k = r - l + 1 ;
304+ s .push (s [s .length - 1 ] + (k * (k + 1 )) / 2 );
305+ l = r + 1 ;
306+ }
307+ }
308+
309+ const ans: number [] = [];
310+ for (const [left, right] of queries ) {
311+ const i = _ .sortedIndex (seg , left + 1 );
312+ const j = _ .sortedIndex (seg , right + 1 ) - 1 ;
313+
314+ if (i > j ) {
315+ const k = right - left + 1 ;
316+ ans .push ((k * (k + 1 )) / 2 );
317+ } else {
318+ const a = seg [i ] - left ;
319+ const b = right - seg [j ] + 1 ;
320+ ans .push ((a * (a + 1 )) / 2 + s [j ] - s [i ] + (b * (b + 1 )) / 2 );
321+ }
322+ }
323+
324+ return ans ;
325+ }
138326```
139327
140328<!-- tabs:end -->
0 commit comments