Problem Description
Given a 1-indexed array of integers nums, we need to distribute all its elements into two separate arrays, arr1 and arr2, by processing nums sequentially with n operations. The rules to decide where to add each nums[i] are based on a helper function greaterCount(arr, val) that counts how many elements in arr are strictly greater than val. Specifically:
- First, add nums[1] to arr1.
- Second, add nums[2] to arr2.
- For each subsequent element nums[i]:
- If greaterCount(arr1, nums[i]) > greaterCount(arr2, nums[i]), add nums[i] to arr1.
- If greaterCount(arr1, nums[i]) < greaterCount(arr2, nums[i]), add nums[i] to arr2.
- If they are equal, add nums[i] to the array with fewer elements.
- In case of a tie in size, add nums[i] to arr1. Finally, return the result array obtained by concatenating arr1 and arr2.
Key Insights
- The challenge is to efficiently compute greaterCount(arr, val) repeatedly as elements are inserted.
- A naïve scan for each query would be too slow given n can be as large as 10^5.
- Using Binary Indexed Trees (or Segment Trees) allows efficient insertion and range queries.
- Two BITs are maintained, one for each array, using coordinate compression since the elements can be as large as 10^9.
- Simulation is performed in order while following the provided decision rules.
Space and Time Complexity
Time Complexity: O(n log n) due to BIT update and query operations. Space Complexity: O(n) for storing the BITs and the resulting arrays.
Solution
We simulate the process of assigning each element to either arr1 or arr2. To quickly count the number of elements greater than a given value, we use two Binary Indexed Trees (BITs). Each BIT supports:
- update: inserting an element in O(log n).
- query: summing frequencies in a range in O(log n).
Since the element values can be very large (up to 10^9), we use coordinate compression to map each value to a smaller range [1, m]. For each element in nums:
- Query BIT1 and BIT2 to obtain the number of elements in arr1 and arr2 that are greater than the current element.
- Decide which array to add the element to using the comparison rules.
- Update the corresponding BIT with the current element’s frequency.
- Append the element to the respective array. Finally, the result is obtained by concatenating arr1 and arr2.
The BIT data structure is the key trick that allows efficient simulation.