主席树(函数式线段树)学习小结(附手绘讲解图片)

本文深入探讨了主席树(Segment Tree)作为离线数据结构的应用,并结合前缀和思想,优化了区间查询与修改操作的效率。通过实例讲解如何构建主席树以及在特定场景下的应用策略,包括修改操作的优化方法。文章还提供了关键代码示例,旨在帮助开发者理解并高效实现这一技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主席树是一种离线数据结构,是由很多棵线段树组成的。


第i棵线段树存的是前i个数的信息:

每一个线段存数字的出现次数(因此建树之前要离散化)。


那么n棵线段树不会MLE吗?


当然会了!


但是我们发现第i棵线段树和第i-1棵线段树是非常相似的,有许多结点完全相同,因此可以借用之前的结点,没必要新建结点。


具体建树方法建下图:


序列为 1 3 4 2




那么如果要询问i-j之间数字出现的次数怎么办呢?


因为每一棵线段树的区间都是相同的,所以要求l-r之间的数字的出现次数只要用前r位出现的次数减去前l-1位出现的次数,就是ans



但是如果有修改操作怎么办?


如果沿用上面的做法,那么修改操作是O(nlogn)的,查询是O(1)的,修改要花好长时间。。。


前缀和联想到了树状数组,那么将前缀和用树状数组维护的话修改是O(logn*logn),查询时O(logn),查询的时间虽然变长,但是修改的时间缩短许多!!


注意:

函数式线段树的数组要开大一点!!


代码:

无修改求区间第k大:

POJ2104 见这里


有修改求区间第k大:

BZOJ1901 见这里





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值