Complexity of testing membership in a disjoint set
There's an easy way to find the node that contains a given value.  You have two data structures: a union-find data structure (that keeps track of which nodes are in the same equivalence class), and a hashtable (that maps from a value to the node(s) that contain that value).

The MakeSet operation adds a new set to the union-find data structure and adds a new entry to the hashtable.  The Union operation and Find operations use only the union-find data structure.  The "look up a node by value" operation uses the hashtable.

The running time of the MakeSet, Union, and Find operations is as in the underlying union-find data structure.  (MakeSet incurs an extra $O(1)$ (expected, amortized) time to insert into the hashtable, but this doesn't change the overall running time of MakeSet.)   The running time of looking up a node by value is $O(1)$ (expected, amortized) time, if you have a good hash function and if each value is only found in a single node.

This doesn't require duplicating the data, if you use pointers in lieu of duplicating: each entry in the hashtable can have a pointer to the node, and each node has a pointer to the value, so values and nodes aren't duplicated.  Of course, this does increase the memory usage (by at most a constant factor); nothing is free in life.