[POJ 1988]

Cube Stacking

并查集。

题意是,原有30,000个栈,每个栈中有一个cube,总共最多100,000个操作,每个操作可以是将一个栈叠到另一个上,或者是求某个cube下方有多少个cube。

很明显的”由cube指定的stack号来作叠置操作”暗示了要用并查集的。但以前写过的并查集仅能够实现(1)路径压缩;(2)按秩合并。也即f[i]表示的值可以是(1)栈编号(当f[i]>=0;(2)栈大小(当f[i]<0)。由此,不难推出,如果额外增设一个p[i],记录每个cube到栈顶间有多少个cube,那么就可以有: 栈大小 – 上方cube数 – 1 = 下方cube数。 进一步分析p[i]的更新方式,每次作union(a,b)时,是将a整个放在b上的,也即此时p[b]=f[a]。但如果要使p[i]值正确,压缩路径前要记录原父cube,递归处理压缩路径后,将父cube的p值累加到本cube的p值上。 跑出来只有500+ms,改成非递归可能才会快点。