Program to find maximum sum obtained of any permutation in Python

Given an array nums and an array requests where requests[i] = [start_i, end_i], each request asks for the sum of elements from nums[start_i] to nums[end_i] inclusive. We need to find the maximum total sum of all requests among all permutations of nums. The answer should be returned modulo 10^9+7.

Problem Understanding

For example, if nums = [10,20,30,40,50] and requests = [[1,3],[0,1]], we want to arrange the array to maximize the sum. The optimal arrangement [30,50,40,20,10] gives ?

  • Request [1,3]: nums[1] + nums[2] + nums[3] = 50 + 40 + 20 = 110
  • Request [0,1]: nums[0] + nums[1] = 30 + 50 = 80
  • Total sum: 110 + 80 = 190

Algorithm

The key insight is to determine how many times each position gets accessed across all requests, then place larger numbers at positions that are accessed more frequently.

Step 1: Create Events

For each request [start, end], we create start and end events to track when ranges begin and end ?

from collections import defaultdict

def solve(nums, requests):
    # Create events for range starts and ends
    events = []
    for start, end in requests:
        events.append((start, 0))  # 0 for range start
        events.append((end, 1))    # 1 for range end
    
    events.sort()
    print("Events:", events)
    
    # Calculate frequency for each position range
    freq_ranges = defaultdict(list)
    active_count = 0
    i = 0
    n = len(events)
    
    while i < n:
        # Count duplicate events at same position
        duplicates = 1
        while i < n - 1 and events[i+1] == events[i]:
            duplicates += 1
            i += 1
            
        position, event_type = events[i]
        
        if event_type == 0:  # Range start
            active_count += duplicates
            if active_count - duplicates > 0:
                freq_ranges[active_count - duplicates].append((prev_pos, position - 1))
            prev_pos = position
        else:  # Range end
            active_count -= duplicates
            freq_ranges[active_count + duplicates].append((prev_pos, position))
            prev_pos = position + 1
            
        i += 1
    
    print("Frequency ranges:", dict(freq_ranges))
    return freq_ranges

nums = [10, 20, 30, 40, 50]
requests = [[1, 3], [0, 1]]
freq_ranges = solve(nums, requests)
Events: [(0, 0), (1, 0), (1, 1), (3, 1)]
Frequency ranges: {1: [(0, 0), (2, 3)], 2: [(1, 1)]}

Step 2: Assign Values Optimally

Sort numbers in descending order and assign them to positions with highest frequency first ?

from collections import defaultdict

def solve(nums, requests):
    # Create events for range processing
    events = []
    for start, end in requests:
        events.append((start, 0))  # Range start
        events.append((end, 1))    # Range end
    
    events.sort()
    
    # Calculate frequency for each position range
    freq_ranges = defaultdict(list)
    active_count = 0
    i = 0
    n = len(events)
    prev_pos = 0
    
    while i < n:
        duplicates = 1
        while i < n - 1 and events[i+1] == events[i]:
            duplicates += 1
            i += 1
            
        position, event_type = events[i]
        
        if event_type == 0:  # Range start
            active_count += duplicates
            if active_count - duplicates > 0:
                freq_ranges[active_count - duplicates].append((prev_pos, position - 1))
            prev_pos = position
        else:  # Range end
            active_count -= duplicates
            freq_ranges[active_count + duplicates].append((prev_pos, position))
            prev_pos = position + 1
            
        i += 1
    
    # Sort numbers in descending order
    nums.sort(reverse=True)
    
    # Sort frequencies in descending order
    frequencies = list(freq_ranges.keys())
    frequencies.sort(reverse=True)
    
    # Calculate maximum sum
    result = 0
    MOD = 10**9 + 7
    num_index = 0
    
    for freq in frequencies:
        for start, end in freq_ranges[freq]:
            range_length = end - start + 1
            range_sum = sum(nums[num_index:num_index + range_length])
            result += range_sum * freq
            result %= MOD
            num_index += range_length
    
    return result

# Test the solution
nums = [10, 20, 30, 40, 50]
requests = [[1, 3], [0, 1]]
print("Maximum sum:", solve(nums, requests))
Maximum sum: 190

How It Works

The algorithm works by ?

  1. Event Processing: Convert range requests into start/end events
  2. Frequency Calculation: Count how many requests overlap at each position
  3. Optimal Assignment: Place largest numbers at positions accessed most frequently
  4. Sum Calculation: Multiply each range sum by its access frequency

Complete Solution

from collections import defaultdict

def maximumSumPermutation(nums, requests):
    # Create events for range boundaries
    events = []
    for start, end in requests:
        events.append((start, 0))  # 0 = range start
        events.append((end, 1))    # 1 = range end
    
    events.sort()
    
    # Calculate frequency for each position range
    freq_ranges = defaultdict(list)
    active_count = 0
    i = 0
    n = len(events)
    prev_pos = 0
    
    while i < n:
        # Handle duplicate events at same position
        duplicates = 1
        while i < n - 1 and events[i+1] == events[i]:
            duplicates += 1
            i += 1
            
        position, event_type = events[i]
        
        if event_type == 0:  # Range start
            active_count += duplicates
            if active_count - duplicates > 0:
                freq_ranges[active_count - duplicates].append((prev_pos, position - 1))
            prev_pos = position
        else:  # Range end
            active_count -= duplicates
            freq_ranges[active_count + duplicates].append((prev_pos, position))
            prev_pos = position + 1
            
        i += 1
    
    # Sort numbers in descending order for optimal placement
    nums.sort(reverse=True)
    
    # Process frequencies in descending order
    frequencies = sorted(freq_ranges.keys(), reverse=True)
    
    result = 0
    MOD = 10**9 + 7
    num_index = 0
    
    # Assign numbers to positions based on frequency
    for freq in frequencies:
        for start, end in freq_ranges[freq]:
            range_length = end - start + 1
            range_sum = sum(nums[num_index:num_index + range_length])
            result = (result + range_sum * freq) % MOD
            num_index += range_length
    
    return result

# Test with example
nums = [10, 20, 30, 40, 50]
requests = [[1, 3], [0, 1]]
print("Result:", maximumSumPermutation(nums, requests))
Result: 190

Conclusion

This solution uses an event-based approach to calculate position frequencies, then optimally assigns the largest numbers to the most frequently accessed positions. The time complexity is O(n log n) for sorting, making it efficient for large inputs.

Updated on: 2026-03-26T13:48:29+05:30

552 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements