-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathcount-good-subarrays.cpp
More file actions
71 lines (65 loc) · 2.14 KB
/
count-good-subarrays.cpp
File metadata and controls
71 lines (65 loc) · 2.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Time: O(n)
// Space: O(n)
// combinatorics, mono stack
class Solution {
public:
long long countGoodSubarrays(vector<int>& nums) {
const auto& is_proper_subset = [](int a, int b) {
return a != b && (a | b) == b;
};
const auto& is_subset = [](int a, int b) {
return (a | b) == b;
};
vector<int> right(size(nums), size(nums));
vector<int> stk;
for (int i = size(nums) - 1; i >= 0; --i) {
for (; !empty(stk) && is_subset(nums[stk.back()], nums[i]); stk.pop_back());
right[i] = !empty(stk) ? stk.back() : size(nums);
stk.emplace_back(i);
}
int64_t result = 0;
stk.clear();
for (int64_t i = 0, left = -1; i < size(nums); ++i) {
for (; !empty(stk) && is_proper_subset(nums[stk.back()], nums[i]); stk.pop_back());
left = !empty(stk) ? stk.back() : -1;
stk.emplace_back(i);
result += (i - left) * (right[i] - i);
}
return result;
}
};
// Time: O(n)
// Space: O(n)
// combinatorics, mono stack
class Solution2 {
public:
long long countGoodSubarrays(vector<int>& nums) {
const auto& is_proper_subset = [](int a, int b) {
return a != b && (a | b) == b;
};
const auto& is_subset = [](int a, int b) {
return (a | b) == b;
};
vector<int> left(size(nums), -1);
vector<int> stk;
for (int i = size(nums) - 1; i >= 0; --i) {
for (; !empty(stk) && !is_proper_subset(nums[i], nums[stk.back()]); stk.pop_back()) {
left[stk.back()] = i;
}
stk.emplace_back(i);
}
vector<int> right(size(nums), size(nums));
stk.clear();
for (int i = 0; i < size(nums); ++i) {
for (; !empty(stk) && !is_subset(nums[i], nums[stk.back()]); stk.pop_back()) {
right[stk.back()] = i;
}
stk.emplace_back(i);
}
int64_t result = 0;
for (int64_t i = 0; i < size(nums); ++i) {
result += (i - left[i]) * (right[i] - i);
}
return result;
}
};