O(n.logn) implementation