Java TreeSet with PriorityQueue
We want to maintain two pools of servers - a busy pool and an available pool. Every time a request comes in, we will first check which servers in our busy pool 
We want to maintain two pools of servers - a busy pool and an available pool. Every time a request comes in, we will first check which servers in our busy pool become available. Then we iterate over the available pool starting from `i % k` and wrapping around until we find a free server. Then this server is transferred from our available pool to the busy pool. We model the available pool as a sorted set so we can quickly answer queries of the form give me the id right after `x`. The busy pool is modelled as priority queue with key being the finishing time of currently processing request. Once a request arrives (i.e. we iterate to it), then we go over our busy pool to remove servers which stopped processing before the arrival time of the current request and transfer it to the available pool. Once available pool is updated, we assign a server to it.\n\n```\nclass Solution {\n    class Server {\n        final int id;\n        final int busyTime;\n        public Server(int id, int busyTime){\n            this.id = id;\n            this.busyTime = busyTime;\n        }\n    }\n    \n    public List<Integer> busiestServers(int k, int[] arrival, int[] load) {\n        TreeSet<Integer> available = new TreeSet<>();\n        PriorityQueue<Server> busy = new PriorityQueue<>((a, b) -> a.busyTime - b.busyTime);\n        int[] requestCount = new int[k];\n        int n = arrival.length;\n        for(int id = 0; id < k; id++){\n            available.add(id);\n        }\n        \n        for(int i = 0; i < n; i++){\n            int defaultServer = (i % k);\n            while(!busy.isEmpty() && busy.peek().busyTime <= arrival[i]){\n                Server top = busy.poll();\n                available.add(top.id);\n            }\n            \n            if(available.isEmpty())continue;\n            Integer nextServer = available.ceiling(defaultServer);\n            nextServer = (nextServer != null) ? \n                nextServer : available.ceiling(0);\n            int requestEnd = arrival[i] + load[i];\n            available.remove(nextServer);\n            busy.add(new Server(nextServer, requestEnd));\n            requestCount[nextServer]++;\n        }\n        \n        int maxRequests = Integer.MIN_VALUE;\n        List<Integer> busiestServers = new ArrayList<>();\n        for(int id = 0; id < k; id++){\n            maxRequests = Math.max(maxRequests, requestCount[id]);\n        }\n        \n        for(int id = 0; id < k; id++){\n            if(requestCount[id] == maxRequests)busiestServers.add(id);\n        }\n        \n        return busiestServers;\n    }\n}\n```
['Java']