First of all, vertex colors store as 8 bit which means you can store values 0-255 but they will be first divided by 255. So you can control exactly which values are written knowing this.
You just need to use the material function “1d to 2d Index” to do this. Out of pure coincidence I made this about an hour ago for myself and its the exact same thing you are doing:
In this example “Tiles” is the number of sub tiles on each axis which for this 2x2 case means there are 4 tiles total. It could be a V2 but my image was only going to be square so I kept it a scalar. Then when vertex painting the meshes, you just paint the first one as 0/TotalTiles, the second one as 1/TotalTiles, third as 2/TotalTiles and so on. If you have more than 256 total tiles this won’t work.
With just a bit more work you can actually support each sub-texture to be tiling without any seams.