Yes, it's possible. Your fallback proposal of parallel element hierarchies (b1 and c1 if you're inside a1, b2 and c2 if you're in a2) is already halfway there. What you want is essentially that same parallel hierarchy, but with the further twist that the elements you have called b1 and b2 are both called b (and similarly for c1, c2, c).
The key is to bind the name 'b' to an element of one type (call it B1) in the context of a1, and to bind it to a different type (B2) in the context of a2. The name 'c' is then bound to one type (C1) in the context of type B1, and to a different type (C2) in the context of type B2. In type C1, d elements are allowed, and not in type C2.
A fuller description of the technique can be found in a paper I wrote while XSD 1.0 was being developed. It may be observed that the same techniques can be applied in any schema language where the name/type binding can be local to a given context; Relax NG, for example, can do the same kind of thing.