关于主席树

可持久化线段树(主席树) 摘要 主席树,又称可持久化线段树,属于可持久化数据结构。“主席”这一名词是由于发明者缩写为HJT,和某位主席拼音缩写相同(有些牵强),故将该数据结构称为主席树。 主席树既保留了线段树的灵活,也拥有了可持久化数据结构的特点,在处理某些特定问题时有着其它数据结构不具有的优势。 本文将首先介绍什么是“可持久化数据结构”,随后介绍主席树的思想,关于代码实现将结合例题讲解。 可持久化数据结构 可持久数据结构... 阅读详情

什么是主席树?

主席树又叫做可持久化线段树,其实后者才是它的大名只是大家都图方便就叫前者了。

可持久化线段树,一听名字就知道它的两个终点:可持久化,线段树。

都要学主席树了,线段树是什么总归都知道的吧,那什么是可持久化呢?

可持久化理解起来其实也很简单,说白了就是可以查询历史节点就可以叫可持久化了,所以可持久化线段树的意思就是可以查询线段树的历史节点就是可持久化了。

如何实现可持久化?

我们这边先给出一棵线段树吧。

画的不好,大家理解一下就行了

假设说我现在想要单点修改最左边的叶子节点

在这里插入图片描述

那么我们会发现只要修改这个叶子节点以及它所有的祖先节点这条链上的节点就行了,换句话说,我们只要把这条链上的节点保存下来下次查询就行了。

在这里插入图片描述
那我们的选择就是再开一个链,如果他的左节点被修改那么我们就指向他的左节点,右节点同理。

关于代码实现

上面其实已经差不多把主席树的原理讲完了,下面放一下具体的代码实现。

主席树的构建

struct node{int l, r, val;};
auto maketree = [&](auto self, int p, int l, int r) -> int {
    p = ++ cnt;
    if(l == r){
        tree[p].val = nums[l];
        return cnt;
    }
    int mid = (l + r) >> 1;
    tree[p].l = self(self, tree[p].l, l, mid);
    tree[p].r = self(self, tree[p].r, mid + 1, r);
    return p;
};

和线段树使用x<<1x << 1x<<1和x<<1∣1x << 1|1x<<1∣1不同主席树需要一个变量专门存左右节点,因为我们后面还需要开点,左右节点不一定会符合线段树的特性

主席树的单点修改

root[i] = update(update, root[v], 1, n, pos, val);
auto clone = [&](int p) -> int {tree[++ cnt] = tree[p]; return cnt;};
auto update = [&](auto self, int p, int l, int r, int x, int y) -> int {//当前节点 左右边界 目标节点 目标值
    p = clone(p);
    if(l == r){
         tree[p].val = y;
    }else{
         int mid = (l + r) >> 1;
         if(x <= mid) tree[p].l = self(self, tree[p].l, l, mid, x, y);
         else tree[p].r = self(self, tree[p].r, mid + 1, r, x, y);
    }
    return p;
};

我们之前说过如果左右节点被修改那么我们就将新的节点的编号更新它的左右节点。最后存下当前版本的根节点编号,用来下次查询时候使用。

主席树的单点查询

query(query, root[v], 1, n, pos)
auto query = [&](auto self, int p, int l, int r, int x) -> int {
    if(l == r) return tree[p].val;
    else{
        int mid = (l + r) >> 1;
        if(x <= mid) return self(self, tree[p].l, l, mid, x);
        else return self(self, tree[p].r, mid + 1, r, x);
    }
};

查询和线段树比较类似,只是要注意要从历史版本的根节点向下寻找。

【学习笔记】浅谈主席树(可持久化线段树) 主席树上没有主席,就跟老婆饼里没有老婆,Bamboo_Day 里没有 Bamboo 是一样的。之所以叫主席树,是因为发明这个数据结构的人名字缩写为hjt跟某位伟大的主席一样。主席树是在的基础上发展出来的,所以你要先学会当然你还要学会。 阅读详情

相关推荐

【算法学习】主席树入门

主席树入门 原理 主席树入门 主席树,也叫做可持久化线段树,准确来说,应该叫做可持久化权值线段树,因为其中的每一颗树都是一颗权值线段树。 所谓权值线段树,就是指线段树的叶子节点保存的是当前值的个数。这样说起来比较抽象,下面用具体例子来简单阐述。 如有数列:2 1 2 5 1 1 1 3,不难统计出,数列中数字1出现了4次,数字2出现了2次,数字3、数字5都出现了1次,对于这...

Pengwill's Blog 2万+

主席树详解(基础)

可持久化线段树,又称主席树,本文详解它的构成和基础用法

nxhx_的博客 4661

主席树模板总结及题集

介绍篇:http://blog.youkuaiyun.com/metalseed/article/details/8045038  -> 理解篇(配图比较生动):http://blog.youkuaiyun.com/regina8023/article/details/41910615  -> 题目:poj2104 区间查询第k大元素,非递归写法,非递归不好进行回溯操作,递归更好写一些 #include #inc

jerans的博客 2866

主席树(POJ-2104、HDU-2665)

【算法分析】 主席树名称来源于其发明人黄嘉泰的姓名的首字母缩写HJT与我们某位主席姓名的首字母缩写一样。 主席树的经典应用在于求某个区间内的第K小/大数的值。比如区间第K大问题,就是给定一个数列a,询问给定区间[L,R]的第K大值。如对数列a=[4,1,3,2,5],针对询问L=2,R=5,K=2,其答案为2。 主席树是一种可持久化数据结构,即可持久化权值线段树。 为了实现可持久化,就要保存线...

hnjzsyjyj的专栏 3566

动态主席树

写在前面 相对于静态主席树,动态主席树意味着,每个节点可能会修改称为新的值,按照我们平时的想法,一定是在之前要删除的位置上进行-1操作,然后再新插入的位置上+1 解析 静态主席树我们在每个节点处创建一个权值线段树,然后在区间[l,r]求解时,使用第r棵线段树 - 第l-1棵线段树,在这个线段树上进行查询第k大元素的离散位置,然后根据之前进行离散的结果,得到最终的位置 使用ZOJ-2112作...

A_Bo的博客 1082

从零开始用TS开发babylonjs - 本机环境搭建

babylonjs,初始化本地安装,web3d引擎

han3527638的专栏 795

主席树

主席树 主席树本体:一棵线段树 需要注意的是,主席树节点编号方式和普通线段树不同:主席树按照DFS顺序编号。 节点信息:有左右儿子节点的编号,还有该节点代表的离散化区间中出现的数的个数。 静态主席树的基本思想是把原来的n棵线段树合并成一棵,因为每次新加进来一个数,总是只修改一条链上的值,没有必要新建一棵线段树。我们只需要在原来的节点后面增加lognlognlogn个节点就能保留新增的信息,原来的节...

qq_36284852的博客 507

MATLAB App Designer 实现多窗口交互与数据传递实战

本文详细介绍了如何使用MATLAB App Designer实现多窗口交互与数据传递的实战技巧。从基础的多窗口应用设计到高级的动态窗口创建,涵盖了窗口调用控制、数据传递方法、状态管理及用户体验优化等核心内容,帮助开发者高效构建复杂的MATLAB GUI应用。

milk5的博客 665

主席树+可修改主席树

普通主席树 普通主席树比较简单 就是很多个权值线段树 每一次加进去log个节点(每层一个),剩下的节点用原来的线段树中的节点直接连到新节点上就好了 线段树 插入节点 主席树 主席树拆开之后 POJ2104 主席树模板题 代码: 1 #include<algorithm> 2 #include<cstdio&gt...

aozhuan8489的博客 258

保姆级教程:Java调用海康SDK实现录像回放与倍速播放(附完整代码)

本文详细介绍了如何使用Java调用海康SDK实现录像回放与倍速播放功能,包括开发环境配置、设备连接、流媒体处理、倍速播放实现及性能优化等关键步骤。通过完整的代码示例和实战经验,帮助开发者快速构建智能录像回放系统,提升开发效率。

weixin_29285605的博客 357

微信小程序中蓝牙打印机中文编码处理:使用iconv-lite库

本文介绍了微信小程序集成蓝牙打印机时中文乱码问题的解决方案。由于打印机通常仅支持GBK/GB2312编码,而小程序使用UTF-8,导致中文显示异常。通过引入轻量级iconv-lite库进行编码转换,可高效解决该问题。文章详细说明了从库安装、编码转换到蓝牙发送的实现步骤,并提供了完整代码示例。关键注意事项包括编码验证、分段发送和兼容性测试。该方法经实际验证,能有效保障中文打印的准确性,适用于零售、物流等场景。

canglingyue的专栏 1310

主席树总结

主席树总结 主席树一个可持久化数据结构。 什么叫可持久化数据结构???普通数据结构维护的是更新之后的状态,这个状态会覆盖之前的状态,使得之前的状态丢失,但可持久化数据结构并不是这样,通过建立多个不同版本的线段树,使得历史版本的线段树仍然可以查询到,更新并不会影响历史版本的状态,这种就叫可持久化线段树。 主席树其实可以维护的是历史版本的区间信息。 区间第K大 区间中小于某个值的个...

qq_40921866的博客 160

运维系列【仅供参考】:RustDesk部署疑难解答

RustDesk部署疑难解答

weixin_54626591的博客 281

待修主席树

废话 主席树入门那篇博客至今已经一年半了,然而我现在才写待修主席树。 网上很多人的待修主席树讲的不明白,往往是一句话带过,跟没说区别不大,大家上网搜资料学习当然都是想学的细致一点,那么对于写博客的人来说,自然要负起责任来写的详细一点。 希望这篇博客能给你帮助。 进入正题! 前置芝士——主席树入门。 以前的码风不优秀还请见谅qwq…… 在其他的博客里大家都能看到这样一句话: 普通的主席树记录的是...

a_forever_dream的博客 503

热红外图像小目标检测算法综述

热红外小目标检测算法综述,着重介绍基于深度学习的小目标检测算法

Littro Innovations 4244

抖音小程序:解决获取手机号报错 getPhoneNumber:fail auth deny,登录注册时需要获取用户手机号,getPhoneNumber一直提示错误(Uniapp抖音小程序报错也能解决)

抖音字节小程序获取手机号报错getPhoneNumber:fail auth deny,抖音 小程序 获取手机号 报错 getPhoneNumber:fail auth ,抖音小程序获取手机号始终返回拒绝,抖音小程序获取手机号,已经过了试运营期但依旧报错如何解决,调用 tt.getPhoneNumber 接口报错,登录注册时需要获取用户手机号,getPhoneNumber一直提示getPhoneNumber:fail auth deny,此能力仅支持小程序通过试运营期后可用,默认获取权限,无需申请;unia

✅ 精选推荐文章 4305

主席树 总结

主席树 (总结主要是为了给自己看,了解用法,主席树的基本原理和写法请出门左转dalao多多) 思路 在之前写博客的时候曾经说了一句,【线段树的可减性】,用这句话来解释线段树的原理。在之后的学习过程中发现这句话不太准确。 主席树即可持久化线段树,它可以记录对线段树修改过程中,每一次修改时的状态,方便之后回退回当前状态。而同时,对于每一次修改,我们通过节点的重用,尽可能得减少空间开销,因为在单点修改时...

ShadowGhostH的博客 337

Qt垂直滚动条QVerticalScrollBar详解:从基础到实战的控件开发指南

本文系统解析Qt中QVerticalScrollBar的用法,从基础概念到进阶技巧。主要内容包括:1)基础认知:介绍其继承关系、作用及典型应用场景;2)核心用法:创建方法、关键属性配置和信号槽连接;3)进阶技巧:自定义样式表美化外观,以及与自定义内容区域的联动实现;4)实战注意事项,如避免循环触发和高DPI适配等。文章强调掌握QVerticalScrollBar对提升Qt滚动类功能开发效率的重要性,并建议通过自定义文本编辑器实践巩固知识点。

专注现代C++实战,从核心语法到高性能编程,助力开发者深入掌握系统级编程精髓。 759

主席树讲解

转自:https://blog.youkuaiyun.com/a_forever_dream/article/details/80450549 主席树这个名字特别高大上,而且也是一种很6的高端操作啊,之前一直想学都没时间,最近终于花了一天把他给搞明白了 主席树的来源: 主席树发明者fotile,后人也称其为fotile主席。同时主席树也被叫做可持续化线段树等,因为主席树这个名字显得高贵冷艳,所以现...

zx93的博客 667

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

上一篇: 关于反向建图(通过牛客菜肴制作制作来看)
ChikingChen
博客等级 码龄6年 18粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值