simple standerd idea of segment tree :) + binary search
\nFirst see the code then read\n\nhere we have tree things:  seg tree, count  and  time\nsegment tree tells us from l to r we can have what minimum possible val
\nFirst see the code then read\n\nhere we have tree things:  ``` seg tree, count  and  time ```\nsegment tree tells us from ``` l to r ``` we can have what minimum possible value( minimum end time ) and at what index(server)\nseg[idx][0] = tells us at which server\nseg[idx][1] = tells us minimum possible time that any server have finished his tasks so after that it\'s available\n\nbuild tree : simply construct the tree intially with no contrain\nset function : when ever we assign a task to a server we update it\'s time as update segment tree \n\nfind function: if (i%k) server is not available at time then we have to search first on right side (i+1 to n-1) if not found then try left side (0 to i-1)  if still not found drop the task\n\nin find function we are checking is our seg[idx][1] <=val if yess means we have a server which have finished his job before arrival of this current task but remember we need to find closest first one so we will again check on left side of that segment if we find then no need to check right side beacuse every index value on left side is always smaller than side if not found then check right side recursively it\'s some sort of binary search if we found then we try to minimise this thing... \n\n\n```\nclass Solution {\npublic:\n    \n    vector<int> count;\n    vector<int> time;// this tells us till time[i] ith server is busy\n    vector<vector<int>> seg;\n    int n;\n    void build(int idx, int l, int r)  // build the tree\n    {\n        if(l==r)\n        {\n            seg[idx][0]=l;\n            seg[idx][1]=1;\n            time[l]=1;\n            return;\n        }\n        \n        int m=l+(r-l)/2;\n        build(2*idx+1, l,m);\n        build(2*idx+2, m+1,r);\n        seg[idx][0]= min(seg[2*idx+1][0], seg[2*idx+2][0]);\n    }\n    \n    void set(int idx, int l, int r, int li, int val)  // mark the sever and update busy time vector\n    {\n        if(l==li && l==r)\n        {\n            seg[idx][0]=l;\n            seg[idx][1]=val;\n            time[l]=val;\n            return;\n        }\n        if(li<l) return;\n        if(r<li) return;\n        int m=l+(r-l)/2;\n        set(2*idx+1, l,m,li,val);\n        set(2*idx+2, m+1,r,li,val);\n        \n        if(seg[idx*2+1][1]< seg[idx*2+2][1])\n        {\n           seg[idx][0]= seg[2*idx+1][0];\n           seg[idx][1]= seg[2*idx+1][1];\n        }\n        else \n        {\n            seg[idx][1]=seg[2*idx+2][1];\n            seg[idx][0]=seg[2*idx+2][0];\n        }\n        \n    }\n    \n    int find(int idx, int l, int r, int li, int ri, int val)  // binary search \n    {\n        \n        if(l>ri|| r<li) return n+1;\n        int ans= n+1;\n        \n        int m= l+(r-l)/2;\n        if(li<=l && r<=ri)\n        {\n            if(seg[idx][1]>val) return n+1;\n            else ans= seg[idx][0];// minimum possible value that is currently avilable which is less than val\n            \n            if(l==r) return ans;\n            \n            if(seg[2*idx+1][1]<=val) // if something smaller than val is present of left side then no need to search in right side\n            {\n                ans= min(ans, find(2*idx+1, l,m,li,ri,val));\n                return ans;\n            }\n            \n            if(seg[2*idx+2][1]<=val) // search on right side\n            {\n                ans= min(ans, find(2*idx+2, m+1,r,li,ri,val));\n                \n            }\n            return ans;\n            \n        }\n       \n        // search on both side\n        ans= min({ans, find(2*idx+1, l,m, li,ri, val), find(2*idx+2, m+1,r,li,ri, val)});\n        return ans;\n        \n    }\n    vector<int> busiestServers(int k, vector<int>& a, vector<int>& t) \n    {\n        n=k;\n        count.resize(n,0);\n        time.resize(n,0);\n        seg.resize(n*4+10, vector<int>(2,0));\n        \n        build(0,0,n-1);\n        \n        for(int i=0; i<a.size(); i++)\n        {\n            int s=i%k;// if simply it\'s available\n            if(time[s]<=a[i])\n            {\n                count[s]++;\n                set(0,0,n-1,s, a[i]+t[i]);\n            }else\n            {\n                \n                //lets\' search first on right half\n                \n                s= find(0,0,n-1, i%k+1,n-1,a[i]);\n                if(s<n)\n                {\n                    set(0,0,n-1,s,a[i]+t[i]);\n                    count[s]++;\n                    \n                }else\n                {\n                    // left half\n                    \n                    if(i%k==0) continue;  // covered in right half\n                    \n                    s= find(0,0,n-1, 0, (i%k)-1,a[i]);\n                    if(s==n+1) continue;\n                    set(0,0,n-1,s,a[i]+t[i]);\n                    count[s]++;\n                    \n                }\n            }\n            \n        }\n        \n        int maxi=*max_element(count.begin(),count.end()); // maximum count \n        vector<int>ans;\n        for(int i=0; i<n; i++)\n        {\n            if(maxi==count[i]) \n            {\n                ans.push_back(i);\n            }\n        }\n        \n        return ans;\n    }\n};\n\n```
['Binary Search', 'Tree', 'C']