|
| 1 | +// Time: O(n) |
| 2 | +// Space: O(n) |
| 3 | + |
| 4 | +// mono stack, prefix sum, optimized from solution2 |
| 5 | +class Solution { |
| 6 | +public: |
| 7 | + int totalStrength(vector<int>& strength) { |
| 8 | + static const int MOD = 1e9 + 7; |
| 9 | + const auto& add = [&](const int64_t a, const int64_t b) { |
| 10 | + return (a + b) % MOD; |
| 11 | + }; |
| 12 | + const auto& sub = [&](const int64_t a, const int64_t b) { |
| 13 | + return (a - b + MOD) % MOD; |
| 14 | + }; |
| 15 | + const auto& mult = [&](const int64_t a, const int64_t b) { |
| 16 | + return (a * b) % MOD; |
| 17 | + }; |
| 18 | + vector<int64_t> prefix(size(strength) + 1); |
| 19 | + int64_t curr = 0; |
| 20 | + for (int i = 0; i < size(strength); ++i) { |
| 21 | + curr = add(curr, strength[i]); |
| 22 | + prefix[i + 1] = add(prefix[i], curr); |
| 23 | + } |
| 24 | + vector<int> stk = {-1}; |
| 25 | + int result = 0; |
| 26 | + for (int i = 0; i <= size(strength); ++i) { |
| 27 | + while (stk.back() != -1 && (i == size(strength) || strength[stk.back()] >= strength[i])) { |
| 28 | + const int x = stk[size(stk) - 2] + 1; |
| 29 | + const int y = stk.back(); stk.pop_back(); |
| 30 | + const int z = i - 1; |
| 31 | + // assert(all(strength[j] >= strength[y] for j in xrange(x, y+1))) |
| 32 | + // assert(all(strength[j] > strength[y] for j in xrange(y+1, z+1))) |
| 33 | + result = add(result, mult(strength[y], sub(mult(y - x + 1, sub(prefix[z + 1], prefix[y])), mult(z - y + 1, sub(prefix[y], prefix[max(x - 1, 0)]))))); |
| 34 | + } |
| 35 | + stk.emplace_back(i); |
| 36 | + } |
| 37 | + return result; |
| 38 | + } |
| 39 | +}; |
| 40 | + |
| 41 | +// Time: O(n) |
| 42 | +// Space: O(n) |
| 43 | +// mono stack, prefix sum |
| 44 | +class Solution2 { |
| 45 | +public: |
| 46 | + int totalStrength(vector<int>& strength) { |
| 47 | + static const int MOD = 1e9 + 7; |
| 48 | + const auto& add = [&](const int64_t a, const int64_t b) { |
| 49 | + return (a + b) % MOD; |
| 50 | + }; |
| 51 | + const auto& sub = [&](const int64_t a, const int64_t b) { |
| 52 | + return (a - b + MOD) % MOD; |
| 53 | + }; |
| 54 | + const auto& mult = [&](const int64_t a, const int64_t b) { |
| 55 | + return (a * b) % MOD; |
| 56 | + }; |
| 57 | + vector<int64_t> prefix(size(strength) + 1), prefix2(size(strength) + 1); |
| 58 | + for (int i = 0; i < size(strength); ++i) { |
| 59 | + prefix[i + 1] = add(prefix[i], strength[i]); |
| 60 | + prefix2[i + 1] = add(prefix2[i], strength[i] * static_cast<int64_t>(i + 1)); |
| 61 | + } |
| 62 | + vector<int64_t> suffix(size(strength) + 1), suffix2(size(strength) + 1); |
| 63 | + for (int i = size(strength) - 1; i >= 0; --i) { |
| 64 | + suffix[i] = add(suffix[i + 1], strength[i]); |
| 65 | + suffix2[i] = add(suffix2[i + 1], strength[i] * (size(strength) - i)); |
| 66 | + } |
| 67 | + vector<int> stk = {-1}; |
| 68 | + int result = 0; |
| 69 | + for (int i = 0; i <= size(strength); ++i) { |
| 70 | + while (stk.back() != -1 && (i == size(strength) || strength[stk.back()] >= strength[i])) { |
| 71 | + const int x = stk[size(stk) - 2] + 1; |
| 72 | + const int y = stk.back(); stk.pop_back(); |
| 73 | + const int z = i - 1; |
| 74 | + // assert(all(strength[j] >= strength[y] for j in xrange(x, y+1))) |
| 75 | + // assert(all(strength[j] > strength[y] for j in xrange(y+1, z+1))) |
| 76 | + const int64_t left = mult(z - y + 1, sub(sub(prefix2[y + 1], prefix2[x]), mult(x, sub(prefix[y + 1], prefix[x])))); |
| 77 | + const int64_t right = mult(y - x + 1, sub(sub(suffix2[y + 1], suffix2[z + 1]), mult(size(strength) - (z + 1), sub(suffix[y + 1], suffix[z + 1])))); |
| 78 | + result = add(result, mult(strength[y], add(left, right))); |
| 79 | + } |
| 80 | + stk.emplace_back(i); |
| 81 | + } |
| 82 | + return result; |
| 83 | + } |
| 84 | +}; |
0 commit comments