You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Observe that the connected components are in contiguous ranges (simple case analysis: suppose we can go from i -> j for i < j, then we can go to anything between i and j).
3
+
* Consider going through the array from the left to right. We figure out how big the leftmost connected component is. To do so, we repeatedly expand it to the right as long as
4
+
* the maximum of the connected component is bigger than some element on the right. For the sake of simplicity, we pick the minimum element on the right to expand to. When we can
5
+
* no longer expand, that is the largest connected component. We can then recurse to the subproblem of dealing with the next connected component starting immdiately after the
6
+
* current connected component. Observe that we can do up to O(n) expansions in total since each expansion increses the size of some connected component by at least 1 and the
7
+
* sum of connected component sizes is n. We can use either a sparse table or segment tree for finding the index of the minimum element of a range, I just chose a segment tree
8
+
* because I had the code for it but a sparse table is more efficient.
9
+
*
10
+
* Time complexity: O(n log n) for each test case
11
+
* Space complexity: O(n)
12
+
*/
13
+
#pragma GCC optimize("Ofast")
14
+
#pragma GCC optimize("unroll-loops")
15
+
#include<bits/stdc++.h>
16
+
usingnamespacestd;
17
+
18
+
typedeflonglong ll;
19
+
typedef vector<int> vi;
20
+
#definefast_cin() \
21
+
ios_base::sync_with_stdio(false); \
22
+
cin.tie(NULL); \
23
+
cout.tie(NULL);
24
+
25
+
typedeflonglong ll;
26
+
structNode {
27
+
int s, e;
28
+
ll mn, mx, sum, add_val, set_val;
29
+
ll mn_idx, mx_idx; // left most index of minimum and maximum
30
+
ll num_mn, num_mx; // number of minimums and maximums
0 commit comments