- Choose the invariant that makes a window valid or useful.
- Advance the right boundary and add the new element.
- Move the left boundary only as needed while maintaining the invariant and updating the answer.
Code notes
- 72 lines of C++ from the credited upstream file count-good-subarrays.cpp.
- The implementation visibly relies on sequence storage.
- 9 loop blocks detected.
Complexity
Confirm that neither pointer moves backwards; if so, the scan is usually linear apart from the window’s data-structure operations.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
123 45class Solution {6public:7 long long countGoodSubarrays(vector<int>& nums) {8 const auto& is_proper_subset = [](int a, int b) {9 return a != b && (a | b) == b;10 };11 12 const auto& is_subset = [](int a, int b) {13 return (a | b) == b;14 };15 16 vector<int> right(size(nums), size(nums));17 vector<int> stk;18 for (int i = size(nums) - 1; i >= 0; --i) {19 for (; !empty(stk) && is_subset(nums[stk.back()], nums[i]); stk.pop_back());20 right[i] = !empty(stk) ? stk.back() : size(nums);21 stk.emplace_back(i);22 }23 int64_t result = 0;24 stk.clear();25 for (int64_t i = 0, left = -1; i < size(nums); ++i) {26 for (; !empty(stk) && is_proper_subset(nums[stk.back()], nums[i]); stk.pop_back());27 left = !empty(stk) ? stk.back() : -1;28 stk.emplace_back(i);29 result += (i - left) * (right[i] - i);30 }31 return result;32 }33};34 35363738class Solution2 {39public:40 long long countGoodSubarrays(vector<int>& nums) {41 const auto& is_proper_subset = [](int a, int b) {42 return a != b && (a | b) == b;43 };44 45 const auto& is_subset = [](int a, int b) {46 return (a | b) == b;47 };48 49 vector<int> left(size(nums), -1);50 vector<int> stk;51 for (int i = size(nums) - 1; i >= 0; --i) {52 for (; !empty(stk) && !is_proper_subset(nums[i], nums[stk.back()]); stk.pop_back()) {53 left[stk.back()] = i;54 }55 stk.emplace_back(i);56 }57 vector<int> right(size(nums), size(nums));58 stk.clear();59 for (int i = 0; i < size(nums); ++i) {60 for (; !empty(stk) && !is_subset(nums[i], nums[stk.back()]); stk.pop_back()) {61 right[stk.back()] = i;62 }63 stk.emplace_back(i);64 }65 int64_t result = 0;66 for (int64_t i = 0; i < size(nums); ++i) {67 result += (i - left[i]) * (right[i] - i);68 }69 return result;70 }71};72