Skip to content

Commit 06afc32

Browse files
authored
Create sum-of-total-strength-of-wizards.cpp
1 parent 6561890 commit 06afc32

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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

Comments
 (0)