树状数组使用总结

有关积分的表述只是我自己的理解,不喜勿喷。。。
一次积分需要dalta有点思考,而二次积分对dalta思考就有点麻烦了。

一、直接维护最终结果

这个方式很直接,题目让求什么你就维护什么
适用于:要改变单项而结果只是对单项积分的题目。

  1. 滑动窗口
    例如:坐火车
    大致的题意是给一个n个数,求第i个数在数组中左右两边相同数值的配对数之和且数值范围在[l, r]之间,询问可以算作i l r(题目输入做了简化)
    如第i个数左边a个m,右边b个m,且m∈[l, r]那么数值对总和的贡献为a*b (m这个数形成了ab对组合)
    而这个题目比较特殊:每个i是连续的直接暗示了你使用滑动窗口(和莫队类似),然而我实在是太菜了,看不出来这个暗示。
    n个i l r又是5e5的规模,显然大概率与树状数组或线段树有关(然而我这个菜鸡还是没想到TvT)
    在这里树状数组直接以数据值域开空间,直接维护滑动到第i个数时每个数的贡献(不限制数值范围),i l r就是查询[l, r]里的贡献之和。而i滑动时就是对树状数组的改变操作,i - 1滑动到i就表示左边新增加num[i],右边减少num[i],设此前左边a个num[i],右边b个num[i]具体到对结果改变为ab - (a+1)(b-1) = b - a,即对树状数组第i位改变为b - a。(这个改变量还是要稍稍思考下的)
    而维护a、b比较简单对值域开两个数组即可,代码是从别处学习的,就不贴了。

维护最终结果的改变量

维护改变量是因为改变单项,但对单项一次积分只能求改变量的题目,简而言之
适用于:要改变单项,但最终结果是对单项二次积分的题目
显然这类题目输入n个数字,每输入一个数字的过程就是对一次积分的改变,查询到[l, r] (l和r多半是1和n)然后加到一个sum去(二次积分)。
对单项积分就是Δ,每次查询结果就是sum + Δ
例如: 牛牛的Link Power II
要思考题目中将0变1或1变0的过程对sum有什么影响,如何用数学语言表达Δ。比如这一题Δ = Δ1 + Δ2, Δ1= y前面1的数量乘y - y前面所有1的位置和, Δ2 = y后面1的数量乘y - y后面所有1的位置(反过来数位置)
而树状数组维护1的数量和1位置即可便于求和。
未完待续…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值