谈区间合并线段树
2011-08-29 10:45
225 查看
对于以前做的区间合并线段树颇有微词,对于大神们使用三个数组来记录节点的情况很是不解。对于当前点,只需要能提供所需的w长度区间即可向下进行判断,左子树优先提供,左右子树合并提供,右子树最后提供,否则输出不可行。
故我认为只需要一个记录当前节点的情况的数组即可,不需要三个数组,故用一个数组实际编写了代码。后发现此法是不行的.... 首先判断左右子树能否提供的问题,lsum+rsum>=w则返回m-lsum+1,这样用三个数组很方便,若用一个数组会有很多bug,因为一个数组只是记录自己的情况:左右子树提供给自己的东西。而没有考虑区间的连续性。举例来说:1-10的线段树,左子树右子树分别提供4,但是5,6两点已经被占,这时要提供8长度的区间显然不可能,但是只用一个数组会出现可行的情况而且答案是2.为何要使用三个数组?因为我对这些数组各自的功能不是很清楚,现在来看,lsum与rsum有各自的用处。lsum,rsum各自记录当前点向左向右的连续区间各多长,也就是说这两个数组实际上起的作用就是用来判断区间连续与否。
void PushUp( int rt,int m )
{
lsum[rt]=lsum[rt<<1]; //当前lsum直接取左子树的lsum[]值
rsum[rt]=rsum[rt<<1|1]; //当前sum直接取右子树的rsum[]值
if( lsum[rt]==(m-(m>>1)) )lsum[rt]+=lsum[rt<<1|1];//若左子树是满的,则向右拓展 求和
if( rsum[rt]==m>>1 )rsum[rt]+=rsum[rt<<1];//若右子树是满的,则向左拓展 求和
msum[rt]=max( lsum[rt<<1|1]+rsum[rt<<1],max( msum[rt<<1],msum[rt<<1|1]) );
//当前msum的值为左右子树中空闲点,和 左子树的右边和右子树的左边的和中最大值
}
合并区间的重要操作就在于PushUp操作中,其他的地方lsum与rsum用法相同,共同更新,这也是我产生错觉的原因。看来对于理解这些算法真的很是重要啊~ 我果然还是太弱了!加油!!
故我认为只需要一个记录当前节点的情况的数组即可,不需要三个数组,故用一个数组实际编写了代码。后发现此法是不行的.... 首先判断左右子树能否提供的问题,lsum+rsum>=w则返回m-lsum+1,这样用三个数组很方便,若用一个数组会有很多bug,因为一个数组只是记录自己的情况:左右子树提供给自己的东西。而没有考虑区间的连续性。举例来说:1-10的线段树,左子树右子树分别提供4,但是5,6两点已经被占,这时要提供8长度的区间显然不可能,但是只用一个数组会出现可行的情况而且答案是2.为何要使用三个数组?因为我对这些数组各自的功能不是很清楚,现在来看,lsum与rsum有各自的用处。lsum,rsum各自记录当前点向左向右的连续区间各多长,也就是说这两个数组实际上起的作用就是用来判断区间连续与否。
void PushUp( int rt,int m )
{
lsum[rt]=lsum[rt<<1]; //当前lsum直接取左子树的lsum[]值
rsum[rt]=rsum[rt<<1|1]; //当前sum直接取右子树的rsum[]值
if( lsum[rt]==(m-(m>>1)) )lsum[rt]+=lsum[rt<<1|1];//若左子树是满的,则向右拓展 求和
if( rsum[rt]==m>>1 )rsum[rt]+=rsum[rt<<1];//若右子树是满的,则向左拓展 求和
msum[rt]=max( lsum[rt<<1|1]+rsum[rt<<1],max( msum[rt<<1],msum[rt<<1|1]) );
//当前msum的值为左右子树中空闲点,和 左子树的右边和右子树的左边的和中最大值
}
合并区间的重要操作就在于PushUp操作中,其他的地方lsum与rsum用法相同,共同更新,这也是我产生错觉的原因。看来对于理解这些算法真的很是重要啊~ 我果然还是太弱了!加油!!
相关文章推荐
- hdu 3397(线段树区间合并)
- POJ 3667 Hotel 线段树区间合并
- Poj 3667 Hotel 线段树 区间合并
- Hdu 1540 【线段树--区间合并】.cpp
- hdu 5316 Magician(2015多校第三场第1题)线段树单点更新+区间合并
- [POJ3667]Hotel(线段树,区间合并,重写)
- HDU 3308 - LCIS(线段树+区间合并)
- POJ3667——线段树区间合并(未搞透)——Hotel
- UVA-11235-线段树加区间合并
- HDU 3308 LCIS(线段树区间合并)
- HDU 4351 Digital root 线段树区间合并
- HUD 3911 Black And White 线段树 区间更新 + 区间合并
- hdu 3667 线段树区间合并
- poj 3667 Hotel(线段树区间合并&Splay解法)
- HDU 3308 LCIS 最长上升字串(线段树区间合并)
- hdu 3308 LCIS (线段树区间合并)
- Hdu 1540 Tunnel Warfare【线段树区间合并学习】
- 线段树练习——区间合并
- 【HDU1540】【线段树】【区间合并】【一个PushUp合并还有下去的时候取区间】【可作为模板】
- 【HDU】3308 LCIS (线段树-区间合并)