2281. Sum of Total Strength of Wizards

Difficulty:
Related Topics:
Similar Questions:

Problem

As the ruler of a kingdom, you have an army of wizards at your command.

You are given a 0-indexed integer array strength, where strength[i] denotes the strength of the ith wizard. For a contiguous group of wizards (i.e. the wizards' strengths form a subarray of strength), the total strength is defined as the product of the following two values:

Return **the *sum* of the total strengths of all contiguous groups of wizards**. Since the answer may be very large, return it *modulo* 10^9 + 7.

A subarray is a contiguous non-empty sequence of elements within an array.

  Example 1:

Input: strength = [1,3,1,2]
Output: 44
Explanation: The following are all the contiguous groups of wizards:
- [1] from [1,3,1,2] has a total strength of min([1]) * sum([1]) = 1 * 1 = 1
- [3] from [1,3,1,2] has a total strength of min([3]) * sum([3]) = 3 * 3 = 9
- [1] from [1,3,1,2] has a total strength of min([1]) * sum([1]) = 1 * 1 = 1
- [2] from [1,3,1,2] has a total strength of min([2]) * sum([2]) = 2 * 2 = 4
- [1,3] from [1,3,1,2] has a total strength of min([1,3]) * sum([1,3]) = 1 * 4 = 4
- [3,1] from [1,3,1,2] has a total strength of min([3,1]) * sum([3,1]) = 1 * 4 = 4
- [1,2] from [1,3,1,2] has a total strength of min([1,2]) * sum([1,2]) = 1 * 3 = 3
- [1,3,1] from [1,3,1,2] has a total strength of min([1,3,1]) * sum([1,3,1]) = 1 * 5 = 5
- [3,1,2] from [1,3,1,2] has a total strength of min([3,1,2]) * sum([3,1,2]) = 1 * 6 = 6
- [1,3,1,2] from [1,3,1,2] has a total strength of min([1,3,1,2]) * sum([1,3,1,2]) = 1 * 7 = 7
The sum of all the total strengths is 1 + 9 + 1 + 4 + 4 + 4 + 3 + 5 + 6 + 7 = 44.

Example 2:

Input: strength = [5,4,6]
Output: 213
Explanation: The following are all the contiguous groups of wizards: 
- [5] from [5,4,6] has a total strength of min([5]) * sum([5]) = 5 * 5 = 25
- [4] from [5,4,6] has a total strength of min([4]) * sum([4]) = 4 * 4 = 16
- [6] from [5,4,6] has a total strength of min([6]) * sum([6]) = 6 * 6 = 36
- [5,4] from [5,4,6] has a total strength of min([5,4]) * sum([5,4]) = 4 * 9 = 36
- [4,6] from [5,4,6] has a total strength of min([4,6]) * sum([4,6]) = 4 * 10 = 40
- [5,4,6] from [5,4,6] has a total strength of min([5,4,6]) * sum([5,4,6]) = 4 * 15 = 60
The sum of all the total strengths is 25 + 16 + 36 + 36 + 40 + 60 = 213.

  Constraints:

Solution

class Solution {
    private static int mod = (int) 1e9 + 7;

    public int totalStrength(int[] nums) {
        int n = nums.length;
        long[] forward = new long[n];
        long[] backward = new long[n];
        long[] prefix = new long[n + 1];
        long[] suffix = new long[n + 1];
        forward[0] = prefix[1] = nums[0];
        backward[n - 1] = suffix[n - 1] = nums[n - 1];
        for (int i = 1; i < n; ++i) {
            forward[i] = nums[i] + forward[i - 1];
            prefix[i + 1] = prefix[i] + forward[i];
        }
        for (int i = n - 2; 0 <= i; --i) {
            backward[i] = nums[i] + backward[i + 1];
            suffix[i] = suffix[i + 1] + backward[i];
        }
        long res = 0;
        Deque<Integer> dq = new LinkedList<>();
        for (int i = 0; i < n; ++i) {
            while (!dq.isEmpty() && nums[dq.peekLast()] >= nums[i]) {
                int cur = dq.pollLast();
                int prev = dq.isEmpty() ? -1 : dq.peekLast();
                res =
                        (res
                                        + getSum(
                                                        nums, forward, prefix, backward, suffix,
                                                        prev, cur, i)
                                                * nums[cur])
                                % mod;
            }
            dq.add(i);
        }
        while (!dq.isEmpty()) {
            int cur = dq.pollLast();
            int prev = dq.isEmpty() ? -1 : dq.peekLast();
            res =
                    (res
                                    + getSum(nums, forward, prefix, backward, suffix, prev, cur, n)
                                            * nums[cur])
                            % mod;
        }
        return (int) res;
    }

    private long getSum(
            int[] nums,
            long[] forward,
            long[] prefix,
            long[] backward,
            long[] suffix,
            int prev,
            int cur,
            int next) {
        long sum = ((cur - prev) * (long) nums[cur] % mod) * (next - cur) % mod;
        long preSum = getPresum(backward, suffix, prev + 1, cur - 1, next - cur);
        long postSum = getPostsum(forward, prefix, cur + 1, next - 1, cur - prev);
        return (sum + preSum + postSum) % mod;
    }

    private long getPresum(long[] backward, long[] suffix, int from, int to, int m) {
        int n = backward.length;
        long cnt = to - from + 1L;
        return (suffix[from] - suffix[to + 1] - cnt * (to + 1 == n ? 0 : backward[to + 1]) % mod)
                % mod
                * m
                % mod;
    }

    private long getPostsum(long[] forward, long[] prefix, int from, int to, int m) {
        long cnt = to - from + 1L;
        return (prefix[to + 1] - prefix[from] - cnt * (0 == from ? 0 : forward[from - 1]) % mod)
                % mod
                * m
                % mod;
    }
}

Explain:

nope.

Complexity: