树(3.16

一道树状数组,一道图论,一道树链剖分

seqmod:如何将边权有序求和

先了解一下暴力30

模拟一下可以知道怎么处理

处理边权:将边权赋给它连接的两点(u,v)中的v

求和:(求lca,从链的两边往上跳,跳到lca)

有序:往上跳的时候,右子树(下几层)下面的点值最大,正序推

左子树(下几层)点值最小,逆序推

再了解一下大佬教的正解

大致思想:其实处理的很像是快读,ret=ret*10+p

但是很明显的是你一个个往上跳绝对绝对会超时,这时候我们就想到了倍增-->一次跳2的几次幂,那么这时候乘的肯定就不是2的0次方了而是2的i-1次方

我们考虑从下往上合并时的通解,(从上往下就同理,很好想了),跳一步合并的是a*10+b(下面的链是a,上面的是b)详见p201算法竞赛,那么跳2的i-1,通解就是a*10^2^(i-1)+b

 

rotinv : 树状数组求逆序对

去推如何从上一个状态到下一个状态(因为不可能每一个序列求一次逆序对),去找递推式

求逆序对:归并排序(O(N+M)logM)还是很大的

 

rise:

惊不惊喜

它其实是道图论题

首先肯定考虑相邻的,前面的大后面一定看不到,那么就把其建一条边,用dfs

但是怎么用树状数组来实现呢?

(好吧,其实也可以用树做啦)

正解:(其实就是贪心,每加入一个节点,去找个h——取max来更新,找以nd为节点中,询问去掉nd 这个节点中小于等于h
的数之后这个区间对应的答案.)

用线段树解决,每个节点维护:
• 最大值:vmax
• 这个区间对应的答案:c1
• 这个区间的右儿子(如果有的话)去掉小于等于左儿子最大值以后的剩下
的那些数对应的答案:c2
每个节点支持一种询问query(nd,h):询问去掉nd 这个节点中小于等于h
的数之后这个区间对应的答案.
假如我们可以实现上面这个操作的话,我们先将询问区间[L;R] 对应的那些
节点提取出来排好:nd1, nd2, nd3, ... nds.
query(nd1,0) + query( nd2, max(nd1)) + query(nd3,max(nd1,nd2)) + ... 就
是答案.
我们考虑怎样实现这个询问过程query(nd,h):
如果是叶子节点,只需要返回[h < a]  
如果h < nd 左儿子最大值,则返回query(nd 左儿子,h) + 右儿子c2
如果h >= nd,则返回query(nd 右儿子,h)
其实可以将query 看成我用h 去砍一刀,然后计算答案,上面的过程的正确
性还是比较容易理解的,如果我还有什么没有说清楚的可以看一下代码.
容易发现query 每次最多选两个儿子中的一个节点走下去,所以最多走
O(logn) 个节点,所以复杂度是O(logn) 的.
每个节点在算c2 时需要调用一次query,所以build 的时间复杂度是
O(nlogn) 的.
询问的时候,最多提取出来O(logn) 个区间,每个区间进行一次O(logn) 的
询问,所以单次询问是O(log2n) 的.
总的复杂度是O(nlogn + mlog2n) 的.

 

好吧,总结一下心得:线段树在处理区间时最重要的就是区间合并

 

转载于:https://www.cnblogs.com/lkx422/p/10542710.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值