这两天一直在看各种树~划分树,左偏树,主席树,伸展树~~~好乱~~
一听到主席树这个名字的时候感觉好奇怪,为什么会叫主席树,感觉好难好高大上,所以一直敬而远之,,,,,主席树是一个大牛的拼音缩写HJT(hu jingtao),额~~大牛就是厉害!!!
昨晚上bili发现了一个主席树视频,突然感觉好开心,终于有教程了,哈哈哈~~~发现up主还上传了其他 的算法教程,,,,于是叫注册了bili账号还百度通过了正式会员~~
哈哈~~本来以为b站考试很难,,的确很难(因为之前听朋友说她好艰难才通过、的),但是有百度这种东西~~今天看了up主关于主席树的讲解,虽然明白主席树的什么,但是要手动实现就不会了,看了up的代码好久才渐渐明白,up主的代码好短而已,但是技巧之类的好多,特别是到递归,我觉得递归真的好恶心,因为很难捕捉一下就跳到哪里去了,特别是带返回值的。。。。。后来又看了kuangbin的代码,自己又写了一遍,但是Kuangbin的不是递归写的,而我改成了递归的,不知为什么感觉有点成就感,哈哈~至少对代码的理解又加深了一点点。,,好怕过两天就忘的一干二净了,。。
进入正题:
up主连接:主席树 (一开始是通过up的视频学的)
下面是摘抄其他人的:
主席树的主体是线段树,准确的说,是很多棵线段树,存的是一段数字区间出现次数(所以要先离散化可能出现的数字)。举个例子,假设我每次都要求整个序列内的第 k 小,那么对整个序列构造一个线段树,然后在线段树上不断找第 k 小在当前数字区间的左半部分还是右半部分。这个操作和平衡树的 Rank 操作一样,只是这里将离散的数字搞成了连续的数字。
先假设没有修改操作:
对于每个前缀 S1…i,保存这样一个线段树 Ti,组成主席树。这样不是会 MLE 么?最后再讲。
注意,这个线段树对一条线段,保存的是这个数字区间的出现次数,所以是可以互相加减的!还有,由于每棵线段树都要保存同样的数字,所以它们的大小、形态也都是一样的!这实在是两个非常好的性质,是平衡树所不具备的。
对于询问 (i,j),我只要拿出 Tj 和 Ti-1,对每个节点相减就可以了。说的通俗一点,询问 i..j 区间中,一个数字区间的出现次数时,就是这些数字在 Tj 中出现的次数减去在 Ti-1 中出现的次数。
那么有修改操作