Replay attack can be interpreted in two ways on the blockchain:
1. If there is a hard-fork on the blockchain, and the system is spited into two concurrent platforms, there is a possibility to copy one signed transaction from one chain and put this transaction to the other chain. Usually at a hard-fork there is a mechanism that explicitly avoids a replay attack, like there is a modified transaction semantics, or even just one bit on the forked blockchain, so signed transactions of the old chain will not be valid on the forked one.
2. Even without forking there is the possibility to copy an old transaction and try to replay it again on the blockchain. It is not too effective at an UTXO system, because the system will know that the old transaction output has been already spent. However if it is an account/balance based system, further algorithms must be used. One way to avoid replay attack on an account/balance based system is to implement a counter at each variable that has to be increased at each new transaction. Another way can be to create a nonce for each transaction randomly and automatically, the system has to ensure that the same nonce can not be applied two times. There might be some mixed solution as well, where quasi random nonces are used in an incremental fashion, like:
nonce_next = hash(nonce_prev)
In a multi-hash blockchain system we have most likely account/balance based systems, implying that we have to use one of the nonce or counter based solution. That means that the state of the blockchain is actually not the state of all of the balances, but the tuples of balance and nonce
state_i = <balance_i, nonce_i_j >
state_i = <balance_i, nonce_i_j >