虽然又是成段修改,但与 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《统计的力量——线段树全接触》
450

被折叠的 条评论
为什么被折叠?



