You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

54 lines
2.0 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2022_06_2_week;
// 作为国王的统治者,你有一支巫师军队听你指挥。
// 给你一个下标从 0 开始的整数数组 strength 
// 其中 strength[i] 表示第 i 位巫师的力量值。
// 对于连续的一组巫师也就是这些巫师的力量值是 strength  子数组
// 总力量 定义为以下两个值的 乘积 :
// 巫师中 最弱 的能力值 * 组中所有巫师的个人力量值 之和 。
// 请你返回 所有 巫师组的 总 力量之和。由于答案可能很大请将答案对 109 + 7 取余 后返回。
// 子数组 是一个数组里 非空 连续子序列。
// 测试链接 : https://leetcode.cn/problems/sum-of-total-strength-of-wizards/
public class Code02_SumOfTotalStrengthOfWizards {
public static final long mod = 1000000007;
public static int totalStrength(int[] arr) {
int n = arr.length;
long preSum = arr[0];
long[] sumSum = new long[n];
sumSum[0] = arr[0];
for (int i = 1; i < n; i++) {
preSum += arr[i];
sumSum[i] = (sumSum[i - 1] + preSum) % mod;
}
int[] stack = new int[n];
int size = 0;
long ans = 0;
for (int i = 0; i < n; i++) {
while (size > 0 && arr[stack[size - 1]] >= arr[i]) {
int m = stack[--size];
int l = size > 0 ? stack[size - 1] : -1;
// l<当前值,且最近,到不了) m(当前数,做为最小值) i(<=当前数,到不了的!)
ans += magicSum(arr, sumSum, l, m, i);
ans %= mod;
}
stack[size++] = i;
}
while (size > 0) {
int m = stack[--size];
int l = size > 0 ? stack[size - 1] : -1;
ans += magicSum(arr, sumSum, l, m, n);
ans %= mod;
}
return (int) ans;
}
public static long magicSum(int[] arr, long[] sumSum, int l, int m, int r) {
long left = (long) (m - l) * (sumSum[r - 1] - (m - 1 >= 0 ? sumSum[m - 1] : 0) + mod) % mod;
long right = (long) (r - m) * ((m - 1 >= 0 ? sumSum[m - 1] : 0) - (l - 1 >= 0 ? sumSum[l - 1] : 0) + mod) % mod;
return (long) arr[m] * ((left - right + mod) % mod);
}
}