It works in O(nlogn) only if you assume that there are no hash-collisions. If you need an algorithm which has the same or better time complexity and perfomance and is guaranteed to produce correct result for all possible inputs, try to use suffix structures(such as suffix array, suffix tree or suffix automaton).
Edit: Here is a nice explanation of Suffix tree algorithm Stack overflow answer to a question on suffix tree. Some other useful resources are here and @makagonov has nice implementation of suffix tree in c++ here