Java O(N Log K) time complexity solution, using TreeSet and Priority Queue
```\nclass ServerInfo {\n    private int serverId;\n    private int nextAvailableTime;\n    \n    public ServerInfo (int serverId, int nextAvailableTime) {\n   
```\nclass ServerInfo {\n    private int serverId;\n    private int nextAvailableTime;\n    \n    public ServerInfo (int serverId, int nextAvailableTime) {\n        this.serverId = serverId;\n        this. nextAvailableTime = nextAvailableTime;\n    }   \n    \n    public int getNextAvailableTime() {\n        return this.nextAvailableTime;\n    }    \n    \n    public int getServerId() {\n        return this.serverId;\n    }\n}\n\nclass ServerComparator implements Comparator<ServerInfo> {\n    public int compare(ServerInfo s1, ServerInfo s2) {\n        if (s1.getNextAvailableTime() == s2.getNextAvailableTime())\n            return Integer.compare(s1.getServerId(), s2.getServerId());\n        return Integer.compare(s1.getNextAvailableTime(), s2.getNextAvailableTime());\n    }\n}\n\nclass Solution {\n    \n    ServerComparator serverComparator = new ServerComparator();\n    \n    \n    public List<Integer> busiestServers(int k, int[] arrival, int[] load) {\n        \n        int[] serverRequestsCounter = new int[k];\n        \n        \n        // Initially all servers are idle\n        TreeSet<Integer> availableServers = new TreeSet<>();\n        for (int serverId=0; serverId<k; serverId++) {\n            availableServers.add(serverId);\n        }\n        \n        // Maintain the buzy servers in Priority Queue, when new arrival time comes, free up previous servers\n        PriorityQueue<ServerInfo> buzyServers = new PriorityQueue<>(serverComparator);\n        \n        for (int idx=0; idx<arrival.length; idx++) {\n            \n            int arrivalTime = arrival[idx];\n\n            while (!buzyServers.isEmpty() \n                   && arrivalTime >= buzyServers.peek().getNextAvailableTime()) {\n                \n                availableServers.add(buzyServers.poll().getServerId());\n                \n            }\n            \n            if (availableServers.isEmpty())\n                continue;\n            \n            // This will give next server Id which is freed up\n            Integer assignedServerId = availableServers.ceiling(idx % k);\n            \n            if (assignedServerId == null) {\n                assignedServerId = availableServers.first();\n            }\n            \n            serverRequestsCounter[assignedServerId]++;\n            \n            // Remove the assigned server from available pool\n            availableServers.remove(assignedServerId);\n                  \n            // Add the assigned server to buzy pool\n            buzyServers.add(new ServerInfo(assignedServerId, arrivalTime + load[idx]));\n        \n        }\n        \n        return busiestServers(serverRequestsCounter, k);\n    }\n    \n    \n    private List<Integer> busiestServers (int[] serverRequestsCounter, int numServers) {\n        int maxRequests = 0;\n        \n        for  (int i=0; i<numServers; i++) {\n            maxRequests = Math.max(serverRequestsCounter[i], maxRequests);\n        }\n        \n        List<Integer> busiestServers = new ArrayList<>();\n            \n        for (int i=0; i<numServers; i++) {\n            if (serverRequestsCounter[i] == maxRequests) {\n                busiestServers.add(i);\n            }\n        }\n        \n        return busiestServers;\n    }\n}\n
['Tree', 'Heap (Priority Queue)', 'Java']