线段树合并
做永无乡的时候,以为是主席树合并,后来感觉不对劲,唔。
x和y是两颗树的根。
这个算法是从归并算法那引申的。
实际运作的时候,考虑到了线段树的本质:线段树有效节点就是叶子节点。
好像是句废话。
其实不是,这句话启发我们并不需要合并一整棵树,
~-~-~-~-~-~
我们只需要处理好叶子节点,
~-~-~-~-~-~
考虑把y树合并到x上,那么把y树的叶子节点合并到x上,那么y树其他节点就可以抛弃了。
至于是怎么合并,其实并不能一概而论。永无乡每一棵树管理的是同样的岛屿属性,也就是每一棵树的叶子节点本质相同,一一对应,那么合并的话就是对应位置的节点合并。
所以我们递归的时候是同步跟踪两颗树对应位置的。(2-和3-)
从代码上看,有两种返回方式,一种是“1-”,一种是“5-”
1-是访问某一棵树的空结点的情况,那么返回不空的那个的序号给上一层,就完成了这里的归并,注意,x+y不是为了加和,而是为了返回有效节点标号。
5-是中间的节点,因为获取y树叶子就可以,所以 中间节点 就返回x树的原结点即可。
int merge(int x,int y)
{
if(!x||!y)return x+y;//1-
arr[x].ls=merge(arr[x].ls,arr[y].ls);//2-
arr[x].rs=merge(arr[x].rs,arr[y].rs);//3-
upp(x);//4-更新结点的数据域。才彻底完成了归并。
return x;//5-
}
代码就这么短。