Two sets
IntuitionTwo sets are needed. Resources set and handling works set.
Resources set contains all available resources and sorted by resources' id.
Handling works s
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->

Two sets are needed. Resources set and handling works set.
Resources set contains all available resources and sorted by resources' id.
Handling works set contains pair information. (Handling work, and resource that handles work)

Every works are moving between non-handled works set to handling works set or not (if work cannot be handled).
Every resources are moving between (available) resources set to handling works set.

# Approach
<!-- Describe your approach to solving the problem. -->

1. Init resources set with all available resources.
2. Walking through arrival array, we will check that there are available resource that can handle current work.
3. Pop out all works from handling works set that are done, compared to currently arrived work. Push resources that are available again to resources set.
4. Find available resource that fits the criteria from resources set. Since resources set is sorted, the lower bound of i % k (i-th work has arrived and we have total k resources) is a resource to use.
5. Pop out chosen resource from resources set and push the resource with current work (= arrived time + load time) together in handling works set.
6. Keep the number of works for each resources are handling into an array.


# Complexity
- Time complexity:
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
$$O(N*log K)$$

Initialization : $$O(K  log K)$$
Pop-out while loop : $$O(N  log K)$$ 
since it is inside main loop, every works (N) can be pushed and poped only once in tatal view. (Implicit mutual exclusion)
Main loop : $$O(N log K)$$


- Space complexity:
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
$$O(N + K)$$ 

# Code
```cpp []
class Solution {
public:
    vector<int> busiestServers(int k, vector<int>& arrival, vector<int>& load) {
        set<int> available_servers;
        priority_queue<pair<int, int>, vector<pair<int, int>>, 
            greater<pair<int, int>>> handling_works; // {ending time, index}
        vector<int> works(k, 0);

        for (int i = 0; i < k; i++) available_servers.insert(i);
        
        int max_work = 0;
        for (int i = 0; i < arrival.size(); i++) {
            while (!handling_works.empty() && 
            handling_works.top().first <= arrival[i]) {
                auto [_, server] = handling_works.top();
                handling_works.pop();
                available_servers.insert(server);
            }

            if (available_servers.empty()) continue;

            auto it = available_servers.lower_bound(i % k);
            if (it == available_servers.end()) it = available_servers.begin();
            int server = *it;
            available_servers.erase(it);

            handling_works.push({arrival[i]+load[i], server});
            max_work = max(++works[server], max_work);
        }

        vector<int> busiest;
        for (int i = 0; i < k; i++)
            if (max_work == works[i])
                busiest.push_back(i);

        return busiest;
    }
};
```
['C++']