【算法详解-数据结构-线段树】(1)简介

不了解这个数据结构,我们怎么学习呢?
————————————华丽的分割线————————————
一天,你坐在机房里面,惬意的喝着茶,正在打着一场NOIp级的,你由于你的主角光环神犇气场,已经AK了其他所有题目,这时候,有一个附加题蹦了出来。
题目1-1
题目1-2
看这个题目的口气不小,一定是一个很难的题目,于是,你打开翻译器,几阵键盘响后,你脱口而出:“我已经看透你的庐山真面目了!你就是一道数组维护题目!”,于是,你用一个普通数组维护这个输入数列就A掉了这道题。
话说这题真的是NOIp吗?
你又喝了几口茶,接着,又蹦出来一道题:
题目2-1
题目2-2
嗯。。。这题的确是增强了一点点,如果用刚才的方法,每次查询都是1~n的话,复杂度会达到nq,会T。
可这题毕竟还不是你的对手,你用前缀和来维护数组,记s[i]为1~i的和,初始化s[i]后,每个2操作就输出s[r]-s[l-1]就行了,于是,AK不在话下。
于是,又蹦出来了一道题~~(你:烦不烦啊!)~~
题目3-1
题目3-2
然后就尴尬了,如果直接用第一题的方法的话,修改的时间复杂度为1,但查询就会是On的,会T掉。
那如果用第2题的前缀和呢?
查询时间还是O1,没问题,但是修改就不一样了。修改一个数时,我们要把s数组中代表的累加和包括修改的数的东西全部更新,这是On的,会T掉。
嘲笑
难道就没有别的方法吗?
有的
如果我们要找到8个数1,2,3,4,5,6,7,8的和。我们有两个方法。
1(一个很常用的方法):
把1,2相加得3,再把3(是前两个数的和),3相加得6,再把6,4相加得1…最后你将算出36。
2(一个不常用的方法):
把1,2相加得3,再把3(是第三个数),4相加得7,再把5,6相加得11,再把7,8相加得15。
把3,7相加得10,把11,15相加得26,把26,10相加得36
如果你算出来不是这个值,那么恭喜你,你算错了
Q:这两种方法效率一样啊,而且第2个方法还要4-1的空间
A:接下来你就知道了
如果你把1改成0,算第1~第7的和,那怎么办?
1:
直接修改成0,然后把0,2相加得2,再把2…
2:
修改已知的第1个数,第1个+第2个的和,(第1个+第2个的和)+(第3个+第4个的和)的和。
然后把((第1个+第2个的和)+(第3个+第4个的和)的和)+(第5个+第6个的和)+第7个

题外话

Q:那也快不了多少啊

A:但是如果你把数据放大到65536,你会发现第1个方法要计算共65535次,修改1次,第二种方法只要计算16次,修改15次

Q:那第一种方法可以把第一次的答案减去最后一个数,修改一下第一个数产生的影响就行了啊

A:那要是再求3~5的值呢?你的代码就行不通了

#这就是线段树

————————————华丽的分割线————————————

但在实际的应用当中,我刚才的算法还要改一改:修改时还要把总值修改一下,这样如果数据特别没良心每次查询都查总和就可以O1虐爆了

end

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值