-
Notifications
You must be signed in to change notification settings - Fork 119
/
Copy pathSum of Total Strength of Wizards.rs
62 lines (49 loc) · 2.06 KB
/
Sum of Total Strength of Wizards.rs
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
// Runtime: 23 ms (Top 88.89%) | Memory: 7.00 MB (Top 33.33%)
impl Solution {
pub fn total_strength(strength: Vec<i32>) -> i32 {
const MOD: i64 = 1_000_000_007;
let strength = strength.into_iter().map(|x| x as i64).collect::<Vec<_>>();
let N = strength.len();
let N_i64 = strength.len() as i64;
let mut ps_l = vec![0; strength.len() + 1];
let mut pm_l = vec![0; strength.len() + 1];
for i in 0..N {
ps_l[i + 1] = (ps_l[i] + strength[i]) % MOD;
let i_64 = i as i64;
pm_l[i + 1] = (pm_l[i] + (i_64 + 1) * strength[i]) % MOD;
}
let mut ps_r = vec![0; strength.len() + 1];
let mut pm_r = vec![0; strength.len() + 1];
for i in (0..N).rev() {
ps_r[i] = (ps_r[i + 1] + strength[i]) % MOD;
let i_64 = i as i64;
pm_r[i] = (pm_r[i + 1] + (N_i64 - i_64) * strength[i]) % MOD;
}
let mut stack = vec![];
let mut ans = 0_i64;
for right in 0..=N {
while !stack.is_empty()
&& (right == N || strength[*stack.last().unwrap()] >= strength[right])
{
let pivot = stack.pop().unwrap();
let pivot_i64 = pivot as i64;
let left_i64 = stack.last().map(|x| *x as i64 + 1).unwrap_or(0);
let left = left_i64 as usize;
let right_i64 = right as i64;
let left_sum = (MOD + pm_l[pivot + 1]
- pm_l[left]
- left_i64 * (ps_l[pivot + 1] - ps_l[left]) % MOD)
% MOD;
let right_sum = (MOD + pm_r[pivot + 1]
- pm_r[right]
- (N_i64 - right_i64) * (ps_r[pivot + 1] - ps_r[right]))
% MOD;
let all_sum =
(left_sum * (right_i64 - pivot_i64) + right_sum * (pivot_i64 - left_i64 + 1)) % MOD;
ans = (ans + all_sum * strength[pivot]) % MOD;
}
stack.push(right);
}
ans as i32
}
}