Sum of Total Strength of Wizards

Updated on 14 July, 2025
Sum of Total Strength of Wizards header image

Problem Statement

In the context of ruling a kingdom with an army of wizards, each wizard possesses a unique strength which is represented by integers in a 0-indexed array named strength. For each possible contiguous group of wizards, the "total strength" of a group is calculated by multiplying the strength of the weakest wizard in that group with the sum of the strengths of all wizards within that group. The task is to compute the sum of the total strengths for every possible contiguous group or subarray within the strength array. Due to potentially large results, the final output should be presented modulo 10^9 + 7. A subarray is defined as a consecutive sequence of elements from the original array that does not omit any element between the starting and ending indices.

Examples

Example 1

Input:

strength = [1,3,1,2]

Output:

44

Explanation:

The following are all the contiguous groups of wizards:

[1] → min = 1, sum = 1 → 1 * 1 = 1  
[3] → min = 3, sum = 3 → 3 * 3 = 9  
[1] → min = 1, sum = 1 → 1 * 1 = 1  
[2] → min = 2, sum = 2 → 2 * 2 = 4  
[1,3] → min = 1, sum = 4 → 1 * 4 = 4  
[3,1] → min = 1, sum = 4 → 1 * 4 = 4  
[1,2] → min = 1, sum = 3 → 1 * 3 = 3  
[1,3,1] → min = 1, sum = 5 → 1 * 5 = 5  
[3,1,2] → min = 1, sum = 6 → 1 * 6 = 6  
[1,3,1,2] → min = 1, sum = 7 → 1 * 7 = 7  

Total = 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] → min = 5, sum = 5 → 5 * 5 = 25  
[4] → min = 4, sum = 4 → 4 * 4 = 16  
[6] → min = 6, sum = 6 → 6 * 6 = 36  
[5,4] → min = 4, sum = 9 → 4 * 9 = 36  
[4,6] → min = 4, sum = 10 → 4 * 10 = 40  
[5,4,6] → min = 4, sum = 15 → 4 * 15 = 60  

Total = 25 + 16 + 36 + 36 + 40 + 60 = 213

Constraints

  • 1 <= strength.length <= 10^5
  • 1 <= strength[i] <= 10^9

Approach and Intuition

To solve the problem, we need to determine the "total strength" for each possible subarray in the given strength array. Here's the general intuition and approach:

  1. Min Element Calculation For each subarray, compute the minimum value, which represents the strength of the weakest wizard in that group.

  2. Sum of Elements Calculate the sum of all elements in each subarray.

  3. Product for Subarray Multiply the minimum strength by the sum of strengths for each subarray to get the "total strength" of that subarray.

  4. Iterative Solution One could iterate across all possible subarrays, but considering the constraints (length up to 10^5), an O(n²) solution might not be efficient. Hence, efficiency optimizations are crucial.

  5. Optimized Strategy Use a monotonic stack to find the range where each element is the minimum. Also, use a prefix sum and prefix of prefix sum to quickly compute the sum of subarrays.

    • For each index, find the previous and next less elements.
    • Calculate contributions of each element to subarrays where it is the minimum.
    • Aggregate all these contributions using prefix sums efficiently.
  6. Modulo Operation As the final number may be large, perform all operations using modulo 10^9 + 7 to stay within integer limits and return the final result.

This method ensures that we efficiently compute the total strength without redundantly checking all subarrays, making the solution scalable for large inputs.

Solutions

  • Java
java
class Solution {
    public int computeStrength(int[] values) {
        int modulo = (int)1e9 + 7, len = values.length;
    
        Stack<Integer> indxStack = new Stack<>();
        int[] rightSmaller = new int[len];
        Arrays.fill(rightSmaller, len);
        for (int i = 0; i < len; ++i) {
            while (!indxStack.isEmpty() && values[indxStack.peek()] >= values[i]) {
                rightSmaller[indxStack.pop()] = i;
            }
            indxStack.add(i);
        }
    
        int[] leftSmaller = new int[len];
        Arrays.fill(leftSmaller, -1);
        indxStack.clear();
        for (int i = len - 1; i >= 0; --i) {
            while (!indxStack.isEmpty() && values[indxStack.peek()] > values[i])
                leftSmaller[indxStack.pop()] = i;
            indxStack.add(i);
        }
    
        long total = 0;
        long[] cumulativeSum = new long[len + 2];
        for (int i = 0; i < len; ++i)
            cumulativeSum[i + 2] = (cumulativeSum[i + 1] + values[i]) % modulo;
        for (int i = 1; i <= len; ++i)
            cumulativeSum[i + 1] = (cumulativeSum[i + 1] + cumulativeSum[i]) % modulo;
            
        for (int i = 0; i < len; ++i) {
            int left = leftSmaller[i], right = rightSmaller[i];
            int countLeft = i - left, countRight = right - i;
            long negativeSum = (cumulativeSum[i + 1] - cumulativeSum[i - countLeft + 1]) % modulo;
            long positiveSum = (cumulativeSum[i + countRight + 1] - cumulativeSum[i + 1]) % modulo;
    
            total = (total + (positiveSum * countLeft - negativeSum * countRight) % modulo * values[i] % modulo) % modulo;
        }
    
        return (int)(total + modulo) % modulo;
    }
}

This Java solution tackles the problem of computing the sum of the total strength of wizards, utilizing an algorithm that focuses on identifying the strength based on smaller elements to the left and right of each wizard's strength.

Follow these steps in your understanding of the provided solution:

  1. Initialize rightSmaller and leftSmaller arrays to hold the indices of the next smaller element to the right and the last smaller element to the left for each element in the input values array.
  2. Utilize a stack to help determine the nearest smaller values for each element with respect to both left and right sides.
  3. Implement the logic to populate the rightSmaller array by examining elements from left to right. For leftSmaller, the array is examined from right to left.
  4. Compute cumulative sums forward and then backward to facilitate efficient range sum queries, essential for calculating strengths.
  5. For each index, compute the product of the index's value and the difference between sums of elements located between that index and its next and last smaller elements. The aim is to calculate the influence of each wizard's strength based on the strength of surrounding wizards.
  6. Apply modulo operations frequently to ensure the results remain within bounds and avoid integer overflow.
  7. Sum up all calculated strengths to get the final result.

The use of data structures like arrays for direct access and stacks for maintaining indices efficiently handling the problem within acceptable time complexities typical of such range query and modified stack-using problems. This systematic use of modular arithmetic alongside cumulative sums and stack-based index management helps efficiently solve a problem of determining collective strength influenced by neighbors.

  • Python
python
class Calculator:
    def calculateStrength(self, svc: List[int]) -> int:
        modulo, length = 10**9 + 7, len(svc)
    
        # Right bounds for each element where the next smaller exists.
        right_bounds = [length] * length
        temp_stack = []
        for idx in range(length):
            while temp_stack and svc[temp_stack[-1]] >= svc[idx]:
                right_bounds[temp_stack.pop()] = idx
            temp_stack.append(idx)
    
        # Left bounds for each element where the previous smaller exists.
        left_bounds = [-1] * length
        temp_stack = []
        for idx in range(length - 1, -1, -1):
            while temp_stack and svc[temp_stack[-1]] > svc[idx]:
                left_bounds[temp_stack.pop()] = idx
            temp_stack.append(idx)
    
        # Precomputing prefix sums of sums for rapid calculations.
        sum_of_sums = list(accumulate(accumulate(svc, initial=0), initial=0))
        result = 0
    
        # Calculating the contribution of each element.
        for i in range(length):
            l_idx = left_bounds[i]
            r_idx = right_bounds[i]
            l_count = i - l_idx
            r_count = r_idx - i
            negative_sum = (sum_of_sums[i + 1] - sum_of_sums[i - l_count + 1]) % modulo
            positive_sum = (sum_of_sums[i + r_count + 1] - sum_of_sums[i + 1]) % modulo
            result += svc[i] * (positive_sum * l_count - negative_sum * r_count)
            result %= modulo
    
        return result

In this Python solution, the goal is to efficiently calculate the total strength of wizards where the strength is defined by specific boundaries in the svc list, which contains the strength values. The approach uses a stack to determine the next and previous smaller elements for each list element, which defines the valid bounds for subarray calculations affecting a wizard's strength.

Here's an outline of each major part of the solution:

  • Initialization: Constants and structures such as right_bounds, left_bounds, and mod are initialized. These variables are used for storing bounds and the modulo for results, respectively.

  • Stack Operations:

    • Determine right_bounds for each element by maintaining a stack that keeps track of elements until a smaller one is found to the right.
    • Similarly, determine left_bounds by iterating from the end to the start of the list and using a stack to track the smaller elements on the left.
  • Prefix Sums Calculation:

    • Compute prefix sums and prefix sums of sums, which helps in quick range sum calculations.
  • Calculate Total Strength:

    • For each wizard, apply the bounds defined by left_bounds and right_bounds to compute its contributions based on its influence range, both to the left and right. These contributions are weighted by the wizard's strength itself and differences in precomputed prefix sums.
    • Each contribution is accumulated into the result, applying modulo operations to prevent overflow.

This approach ensures that every element's bounds are processed exactly once, and range sum queries required for strength calculation are optimized via prefix sums, making the entire operation efficient even for relatively large inputs.

Comments

No comments yet.