- 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
- 55 lines of C++ from the credited upstream file 2281.cpp.
- The implementation visibly relies on sequence storage.
- 7 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.
1class Solution {2 public:3 int totalStrength(vector<int>& strength) {4 constexpr int kMod = 1'000'000'007;5 const int n = strength.size();6 vector<long> prefix(n);7 vector<long> prefixOfPrefix(n + 1);8 9 10 vector<int> left(n, -1);11 12 13 vector<int> right(n, n);14 stack<int> stack;15 16 for (int i = 0; i < n; ++i)17 prefix[i] = i == 0 ? strength[0] : (strength[i] + prefix[i - 1]) % kMod;18 19 for (int i = 0; i < n; ++i)20 prefixOfPrefix[i + 1] = (prefixOfPrefix[i] + prefix[i]) % kMod;21 22 for (int i = n - 1; i >= 0; --i) {23 while (!stack.empty() && strength[stack.top()] >= strength[i])24 left[stack.top()] = i, stack.pop();25 stack.push(i);26 }27 28 stack = std::stack<int>();29 30 for (int i = 0; i < n; ++i) {31 while (!stack.empty() && strength[stack.top()] > strength[i])32 right[stack.top()] = i, stack.pop();33 stack.push(i);34 }35 36 long ans = 0;37 38 39 for (int i = 0; i < n; ++i) {40 const int l = left[i];41 const int r = right[i];42 const long leftSum = prefixOfPrefix[i] - prefixOfPrefix[max(0, l)];43 const long rightSum = prefixOfPrefix[r] - prefixOfPrefix[i];44 const int leftLen = i - l;45 const int rightLen = r - i;46 ans += strength[i] *47 (rightSum * leftLen % kMod - leftSum * rightLen % kMod + kMod) %48 kMod;49 ans %= kMod;50 }51 52 return ans;53 }54};55