主席树(模板,静态求区间第k大)
模板题目链接:hdu2665
学习主席树,推荐先看b站上的视频了解一下,然后看篇博客,当然一般学个新算法只看博客上的叙述是很难懂的,推荐看完博客之后看代码理解一下
b站视频:https://www.bilibili.com/video/av4619406/?p=1
推荐博客:https://blog.csdn.net/williamsun0122/article/details/77871278
主席树我认为其特点是建立n棵线段树,其中第 i i i颗线段树储存的是第 i i i次修改后的版本信息。但是毫无疑问这样是会超时。
但是在线段树中单点修改过程中,其实只影响了一条链的节点,大约为 O ( l o g n ) O(logn) O(logn)个,如果第 i i i 棵线段树 r t rt rt节点的左儿子没有被修改,那就让rt节点的左儿子指向前一颗线段树的rt节点的左儿子。至于右儿子修改了,就新建一个节点当自己的右儿子。这个操作在递归过程很容易实现。
下面未特别指出时,第 i i i 个数就代表其离散化后的值,
至于区间第k大,原理就是首先建立一整颗空树,并将n个数离散化,然后依次添加这n个数,每添加一个数就新建立一颗这个版本的线段树,并把该值为下标的位置的sum+=1。
其中线段树节点存储的是这个区间数值范围的数的个数,和左右儿子指针。比如第 i i i棵线段树,节点 r t rt rt的区间为 [ l , r ] [l,r] [l,r], s u m [ r t ] sum[rt] sum[rt]就代表添加前面的 i i i个数之后,数值范围为 [ l , r ] [l,r] [l,r]<