In Erlang (and in many other programming languages which include a functional subset), operations on purely functional data structures are frequently limited to O(log n) time complexity: there is no such thing as a true array with constant time access. No destructive updates. Nothing like pointers either.
Because of this, you end up with a bunch of modules like array, dict, gb_trees and whatnot, which are all built either on lists or trees with varying branching factors. None of them do better than O(log n), and list-based solutions don't do better than O(n) (although they can average n/2.)
There is, however, a class of data-structures that allow for amortized constant time for some operations: finger trees and zippers are examples of this.