My understanding is that the archival node stores the state tree for each block -- that's the reason the size is so big. Can someone validate my understanding?
Yes, you're correct. An Ethereum archival node is a geth full node. A full node will download/maintain block header + block data + perform full data validation. This process takes a more time and storage.
For more details, see the answer to this question: What is the parity light pruning mode?
The state is so big because it stores contract data. Contract data is like a binary executable .exe in Windows, it contains instructions to be executed and this takes much bigger space than a signed transaction or an account record. Also, contracts are immutable , once you uploaded it , you can't modify it, so a new version of the executable must be fully uploaded if you have to apply some changes. This is the reason Ethereum's state is so big. It is like a hard disk where files are created but never deleted. In the future this is going to get worse.