【省选】算法总结——线段树

线段树

线段树的操作说实话比较灵活,写法也很多

 

比如往线段树里面插入一段值为c的区间[a, b]

void change(int p,int l,int r,int a,int b,int c)

{

         if(a<=l&&b>=r) { val[p]=c; return; }

         int m=(l+r)>>1;

         if(a<=m) change(p<<1,l,m,a,b,c);

         if(b>m) change((p<<1)+1,m+1,r,a,b,c);

         val[p]=max(val[p<<1],val[(p<<1)+1]);//假设是维护最大值

}

主程序里面调用change(1,1,n,a,b,c) 即可

 

当然,上面只是线段树的一种写法,还有一种写法如下(一看就知道两者的区别了)

void change(int p,int l,int r,int a,int b,int c)

{

         if(a==l&&b==r) { val[p]=c; return; }

         int m=(l+r)>>1;

         if(b<=m) change(p<<1,l,m,a,b,c);//区间[a,b]全在左儿子树上

         else if(a>m) change((p<<1)+1,m+1,r,a,b,c);//区间[a,b]全在右儿子树上

         else{//区间[a,b]分为左右儿子两段 [a,m]和[m+1,b]

                   change(p<<1,l,m,a,m,c);

                   change((p<<1)+1,m+1,r,m+1,b,c);

         }

}

 

我个人比较喜欢前面第一种的写法,原因很简答,代码短

 

 

但是第二种也是必须的,为什么呢?

线段树可以动态修改值,看似是动态维护的,但是它的区间(也就是那棵树)是建好后就无法修改的,也就是“静态建树,动态维护”

那当我们遇到需要修改区间的问题该怎么办呢?我们可以维护每个区间的size(即当前区间中有多少个数),这样我们可以通过size来实现伪动态

算了,说不清楚,以SCOI2006的MinMax为例

http://blog.csdn.net/jiangzh7/article/details/8598061

对于这一题,第一种就显得有点力不从心了

 

 

 

那么查询呢?同样两种写法,这里给出第一种写法(同样是维护最大值)

int query(int p,int l,int r,int a,int b)

{

         if(a<=l&&b>=r) return val[p];

         int m=(l+r)>>1,x1=0,x2=0;

         if(a<=m) x1=query(p<<1,l,m,a,b);

         if(b>m) x2=query((p<<1)+1,m+1,r,a,b);

         return max(x1,x2);

}

 

 

 

 

 

我做过的线段树题目

【重庆省选2006】简单题easy http://blog.csdn.net/jiangzh7/article/details/8533051

Count the Colors (zoj 1610) http://blog.csdn.net/jiangzh7/article/details/8535203

弱点 weakness http://blog.csdn.net/jiangzh7/article/details/8559217

星星 POJ2352 http://blog.csdn.net/jiangzh7/article/details/8592676

Cover http://blog.csdn.net/jiangzh7/article/details/8587583

超市促销 rqnoj572http://blog.csdn.net/jiangzh7/article/details/8614323

动态最值 SCOI2006minmax http://blog.csdn.net/jiangzh7/article/details/8598061

序列操作operationSCOI2010【神目】http://blog.csdn.net/jiangzh7/article/details/8596173

 

 

 

 

小总结一下:

线段树这玩意儿能干的事很多,不过最近听说伸展树比它还要牛逼些,线段树能干的事伸展树都能干,最主要的是能动态修改区间,也就是可以完爆MinMax了!所以最近争取吧伸展树学学

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值