pku 3468 线段树-又是成段修改

虽然又是成段修改,但与 hdu 1698 有点不同

真的是越写越觉得线段树高深,灵活

说说这题,一开始感觉与hdu 1698 差不多(我的感觉向来单纯),很快就写了出来,结果

是果断的WA了,这里的传递的细节还是很值得注意的

WA了,然后想在结构体中增加一个flag域来记录这个区间是否全部的增加都相同,相同则向子

结点传递,在插入时并没有计算出区间的sum ,而是在查询时计算,不过这样让我WA了,TLE了

无数次,原因是,这样在查询是很不好处理

最后接近崩溃,还是乖乖地在insert中计算好sum,总算是过了

 

过是过了,去看了一下status大受打击…………我的用时为1873ms别人竟可以做到250ms,也不知道是怎么写出来的

 

下面是转的:虽不是传说中的250ms 但还是要膜拜下

http://hi.baidu.com/%C1%D9%CA%B1%B1%B8%D3%C3%D5%CB%BA%C5/blog/item/c3fc48277975543fd507420b.html

而张神牛给出的前缀和与差分的做法令人咋舌。。。。

可知,前缀和与差分是相对于数组的逆运算。

所以差分的前缀和就是数组,

而差分在原数组进行区间修改时只需要修改边际的两个节点即可,非常快,

所以就成了维护差分的前缀和的前缀和,

即是数组的前缀和,

但是维护差分的前缀和的前缀和则较为简单。

记数组{ai}前缀和的前缀和位SSi,

前缀和为Si,

再记数组{i*ai}的前缀和为Ti,

则可知SSi=(i+1)*Si-Ti(推一下就知道。。。)

所以只需要再维护一个{i*ai}的前缀和即可。

这样写的话,区间维护区间求和就完全变成了单元素修改前缀求和,用树状数组就能解决。。。。。。

但是每次查询要取4个前缀和。

 

刚开始我还只是以为这个方法只是写起来方便,效率未必高,

结果两个方法都试过交上去以后发现,

无论是时间空间还是编程复杂度都直接秒杀传统方法。。。。。

而且我还是用线段树写的,如果改成树状数组估计时间空间编程复杂度还能进一步降低。。。。。。

 

下边上代码,这个方法来自于清华大学张昆玮大牛的ppt《统计的力量——线段树全接触》

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值