Cube Stacking
Cube Stacking
题目描述,有n个栈每个有一个立方体立方体编号为1到n,现在可以执行两种操作:
1.M x y 将含有x号立方体的栈放在含有y立方体的栈上面
2.C x 输出x立方体下面有多少个立方体。
分析:由题意可知,我需要达到的目标是求出要输出的目标立方体下方有多少个立方体,假设我用h[x]表示x下方有多少个立方体,初始h数组为0。
而合并栈的操作,可以很容易想到使用并查集,现在就需要看看怎么实现对h数组的维护。
首先:
当我们将栈x放到栈y上面的时候,对于x栈中的所有的立方体,其下方立方体的个数都应加上y栈中。所以我们需要另开一个数组deep记录每个栈中的立方体个数。
但是由于时间复杂度的原因,显然我们并不能找到栈y中所有的立方体将他们的h去加上栈x的立方体个数。
这时候就需要我们理解并查集的本质:
图中:fa[4]=fa[5]=2;
fa[2]=fa[3]=1;
fa[1]=1;
当我们寻找4节点的祖先的时候,是递归先找其父亲的节点的父亲。
先使fa[2]=1;
再使fa[4]=1;
这样在向上递归的过程中,递归过程其实相当于该节点上的父亲节点都经过一次。
然后路径上的点都直接成为最高节点的儿子。
当再次寻找时,fa[4]就直接到了根节点。
要是我们将沿途的权值全部相当于是每个节点的权值加了一次。
多次寻找,除根节点外其余节点权值只加一次。
所以我们可以将根节点的值设为0,实际上在这道题根节点我们可以取栈底下的立方体,他下方立方体个数为0.
在寻找父亲节点的时候将,个点的值递归累加就行。
下面展示一些 。
// An highlighted block
int find(int x) {
if(fa[x]!=x) {
int t=fa[x];
fa[x]=find(fa[x]