To eliminate the type switch you have to move responsibilities back to the type that requires a type specific action. This type, in your case the "User", has all the information regarding himself and can easily invoke the proper operation based on this knowledge. And you have to make use of inheritance.
In your case you would have to reflect the user types via simple inheritance or via composition. Your "User" would than have a property "UserType", like in your example, but instead of making it just an "Enum" like type, it becomes a complex type that inherits an "IUserType" interface and knows how to construct its specific dependencies ("UserType" implements "IUserType"). The "IUserType" could expose type specific attributes via a property (e.g. "IUserType.TypeSpecificTree" that returns an "ITypeSpecificTree").
So when in your example a "User" is promoted to premium, you would just set the property to a new instance of the concrete "IUserType" implementation (e.g. PremiumUserType") that executes its specific actions like building the premium tree (an "ITypeSpecificTree" implementation) from your example as well as constructing associated types.
This way the switch statement is eliminated by using composition and inheritance. We transformed the complex "UserType" property into a separate class and then moved type specific responsibilities to the type itself.
The inheritance and especially dependency inversion helped to operate on an object (e.g. getting the user type specific information like (User.IUserType.IUserSpecificTree") without knowing the concrete type. This helped to ensure that we are open for extension. Inheritance also helped to encapsulate type specific behavior to make our code close for modification.
If we need to make changes to how the type specific tree is generated or how this user type behaves, we would only touch the associated "IUserType" implementation but never the "User". If new user types are added (extension), they will have to implement the base interface "IUserType" and no other code, like switch-statements, must be touched to make it work and no more type checks are required.
And to make it complete and to offer some more extensibility, the "User" class should also implement an interface e.g. "IUser" that exposes the user type (e.g. "IUser.IUserType").