01字典树和可持久化01字典树

01字典树

01字典树是一种只有0和1两种边的字典树。可以解决查询第 \(k\) 小,查询 \(x\) 是第几小等问题。

查询第 \(k\)

可以把输入的数转成等长二进制,然后插入01字典树。比如将 \([0,0,1,3,3]\) 插入字典树:

这里红色数字表示以该段为前缀的数的个数,黑色表示对应的数。

假设我们要查询第 \(3\) 小,可以发现根节点的左子树里有 \(3\) 个数,即第 \(3\) 小在左子树内:

接着看,左子树内只有两个数,说明答案在右子树内:

最终我们就得到了答案 \(1\)

观察这个过程,可以发现第 \(k\) 小的求法:

  • 当左子树内的数的个数 \(cnt< k\),则答案在右子树内,\(k\leftarrow k-cnt\)
  • 否则答案在左子树内。

不断递归上述过程,直到找到答案。

空间复杂度 \(O(N \log \max \{a_i\})\),单次查询时间复杂度 \(O(\log \max \{a_i\})\)

代码

int GetNum(int k) {int u = 1, ans = 0;for(int i = 29; i >= 0; --i) {if(cnt[son[u][0]] < k) {k -= cnt[son[u][0]], u = son[u][1], ans = (ans << 1) | 1;}else {u = son[u][0], ans <<= 1;}}return ans;}GetNum(k);

查询 \(x\) 为第几小

这个很容易明白,就不多做解释了。

重复执行以下过程:

  • 如果 \(x\) 在右子树,则 \(ans \leftarrow ans+cnt\),其中 \(ans,cnt\) 分别为答案和左子树的数的数量。
  • 否则什么也不做。
  • 走到对应的儿子上。

最终的答案就为 \(ans+1\)

空间复杂度 \(O(N \log \max \{a_i\})\),单次查询时间复杂度 \(O(\log \max \{a_i\})\)

代码

int GetRnk(int x) {int u = 1, ans = 1;for(int i = 29; i >= 0; --i) {if((x >> i) & 1) {ans += cnt[son[u][0]], u = son[u][1];}else {u = son[u][0];}}return ans;
}GetRnk(x);

\(x\) 与其中一数的最大异或和

贪心地考虑即可:

  • 如果当前这位存在与 \(x\) 的不同的,则选择这一位
  • 否则不选择

空间复杂度 \(O(N \log \max \{a_i\})\),单次查询时间复杂度 \(O(\log \max \{a_i\})\)

代码

int GetMaxXor(int x) {int u = 1, ans = 0;for(int i = 29; i >= 0; --i) {if(cnt[son[u][!((x >> i) & 1)]) {u = son[u][!((x >> i) & 1)], ans = (ans << 1) | 1;}else {u = son[u][(x >> i) & 1], ans <<= 1;}}return ans;
}GetMaxXor(x);

01字典树还有很多用处,这里就不多说了。

可持久化01字典树

可持久化01字典树和01字典树只有一个区别,它可以查询任意时刻的01字典树。

首先,我们能想到的最暴力的方法就是每次修改都复制一颗字典树。虽然这样很明显空间会爆掉,但我们还是先看看。比如在 \([0,0,1,3,3]\) 中再加入一个 \(2\)

你可能会注意到,其中大部分的点都没有变化,只有处于 \(2\) 的这条链上有变化,我们不妨这么做:

可以发现现在总共只加入了 \(O(\log \max \{a_i\})\) 个点!

而可持久化字典树也正是这样运作的,就是把不用修改的子树直接指向之前的。在查找历史版本时直接从对应的根节点搜下去就行了。

空间复杂度 \(O((N+M) \log \max \{a_i\})\),单次插入时间复杂度 \(O(\log \max \{a_i\})\)

代码

void Insert(int x, int id, int pos, int val) {ROOT[id] = ++tot;int u = tot, v = ROOT[x];for(int i = 19; i >= 0; --i) {son[u][(pos >> i) & 1] = ++tot;son[u][!((pos >> i) & 1)] = son[v][!((pos >> i) & 1)];u = son[u][(pos >> i) & 1], v = son[v][(pos >> i) & 1];}cnt[u] = val;
}Insert(x, y, pos, val);

查询区间第 \(k\)

01字典树只能求全体第 \(k\) 小,但无法求区间第 \(k\) 小。而区间第 \(k\) 小也很简单,即两个前缀字典树相减再查询。

空间复杂度 \(O((N+M) \log \max \{a_i\})\),单次查询时间复杂度 \(O(\log \max \{a_i\})\)

代码

int GetNum(int l, int r, int k) {int u = ROOT[r], v = ROOT[l - 1], ans = 0;for(int i = 29; i >= 0; --i) {if(cnt[son[u][0]] - cnt[son[v][0]] < k) {k -= cnt[son[u][0]] - cnt[son[v][0]], u = son[u][1], v = son[v][1], ans = (ans << 1) | 1;}else {u = son[u][0], v = son[v][0], ans <<= 1;}}return ans;
}GetNum(l, r, k);

查询 \(x\) 是区间第几小

两个前缀字典树相减再查询即可。

空间复杂度 \(O((N+M) \log \max \{a_i\})\),单次查询时间复杂度 \(O(\log \max \{a_i\})\)

代码

int GetRnk(int l, int r, int x) {int u = ROOT[r], v = ROOT[l - 1], ans = 1;for(int i = 29; i >= 0; --i) {if((x >> i) & 1) {ans += cnt[son[u][0]] - cnt[son[v][0]], u = son[u][1], v = son[v][1];}else {u = son[u][0], v = son[v][0];}}return ans;
}GetRnk(l, r, x);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/736371.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c# , net 创建树形结构,创建树形节点

/// <summary> /// 生成树形结构 /// </summary> public void GetTreeNode() {//SqlHelper.GetSqlDataReader是封装的查询数据库语句,可根据自己需求封装//假设获取所有一级节点List<Products> products = SqlHelper.GetSqlDataReader(sql);for (int i = 0; …

abc360 E 题解

E 对于位置2~n,它们的概率是相等的。 n*n个(x,y)对。其中x可以等于y。对于x/y,y的逆元rev(y)为mul(y,mod-2)。 加、减、乘、除都可以做。比如48/9和16/3的结果是一样的,48*rev(9)%mod = 16*rev(3)%mod。比如3*rev(2)%mod = (rev(2)+rev(2)+rev(2))%mod.对于每次操作,有多少…

数业智能荣登「全球应用算法模型大赛50强」

近日,由上海市经济和信息化委员会、上海市普陀区人民政府,上海市人工智能行业协会主办,上海人工智能研究院等单位联合承办的《BPAA第四届全球应用算法模型典范大赛》经过一个多月的角逐,最终公布《BPAA第四届全球应用算法模型典范大赛TOP50榜单》。数业智能心大陆凭借独立自…

快速调用 GLM-4-9B-Chat 语言模型

一、确认本机显卡配置二、下载大模型 国内可以从魔搭社区下载, 下载地址:https://modelscope.cn/models/ZhipuAI/glm-4-9b-chat/files 三、运行官方代码import torch from transformers import AutoModelForCausalLM, AutoTokenizerdevice = "cuda"tokenizer = A…

戴尔服务器SQL server数据恢复

服务器数据恢复环境: 一台Dell服务器,共有10块硬盘,配置了raid5磁盘阵列,操作系统:linux,里面存有SQL server数据库。服务器数据恢复故障检测分析: 服务器在正常运行过程中,对服务器进行重装系统操作,操作成功后发现服务器的磁盘分区与原来不同,其中一个分区丢失,其…

网络安全:Nginx安全问题使1400多万台服务器容易受到ddos攻击

据外媒报道,近日 nginx 被爆出存在安全问题,有可能会致使 1400 多万台服务器易遭受 DoS 攻击。 而导致安全问题的漏洞存在于 HTTP/2 和 MP4 模块中。 新版本的Nginx Web服务器已于11月6日发布,用于修复影响1.15.6,1.14.1之前版本的多个安全问题, 该漏洞允许潜在的攻击者触发…

服务器硬盘亮红灯数据恢复

故障服务器数据恢复环境: 一台故障服务器,有3块SAS 320GB的硬盘组建的raid5磁盘阵列。 故障服务器数据恢复检测分析: 服务器运行过程中有一块硬盘的指示灯变为红色,raid5磁盘阵列出现故障,服务器上层操作系统的分区无法识别。服务器数据恢复过程: 1、将故障服务器上磁盘编…

服务器RAID5故障该如何解决

故障服务器恢复环境: 一台HP LH6000的服务器,4块18GB的硬盘做成RAID5磁盘阵列,操作系统为Window 2000,数据库是Server 2000。 故障服务器检测分析: 故障服务器经检测发现,一块硬盘红灯闪亮,机器还在正常运行,但没有多久,系统就不能正常运行,这时才发现另一块硬盘的红…

存储断电导致虚拟机无法启动

故障存储虚拟机环境: 一台VMware虚拟机无法启动(虚拟机中存储了oracle数据库)。故障存储虚拟机检测分析: 发生故障的存是由于机房意外断电导致,清空cache并尝试重新启动该虚拟机但失败。需要对该存储进行数据恢复。 故障虚拟机数据恢复流程: 1.合并虚拟机快照(因虚拟机中…

振弦采集仪在岩土工程监测中的优点与应用

振弦采集仪在岩土工程监测中的优点与应用 河北稳控科技振弦采集仪是一种常用的岩土工程监测仪器,通过测量振弦的振动频率和振幅,可以得到土体的力学特性参数,从而对土体的变形和稳定性进行分析和评估。振弦采集仪具有一些优点,同时在岩土工程的监测中有着广泛的应用。 第一…

程序员悠闲的一天{苏州周末休闲文化1日游

随便写写,平时很忙,苏州,都是姑苏区、园区、吴中区活动的比较多,因为外地朋友来了,他们想去相城区,那就出发吧。明天继续回去写代码搬砖了。拍照技术不行凑合看吧。

冗余组典型配置举例

1、组网需求工作在三层,上下行分别连接两台路由器,两台路由器接口不在同一网段如图所示,Device A和Device B组成IRF,Router 1和IRF相连的接口与Router 2和IRF相连的接口不在同一网段,Router 3和IRF相连的接口与Router 4和IRF相连的接口不在同一网段。 正常情况下,流量走R…

git 通过ssh 拉 gitlab项目代码

通过https 登录token 拉取不到 ,就用ssh吧!先查看本地git的配置 git config --list --global发现没有配置 增加配置 git config --global user.name "beckh" git config --global user.email "自己的邮箱" 生成密钥 ssh-keygen -t rsa -C "自己邮箱…

java实现微信登录

上一篇做了php的微信登录,所以也总结一下Java的微信授权登录并获取用户信息这个功能的开发流程。前言 上一篇做了php的微信登录,所以也总结一下Java的微信授权登录并获取用户信息这个功能的开发流程。 配置 配置什么的就不多说了,详细的配置可以直接前往我上一篇查看。 http…

程序员的零食好物:十分米莲藕汁 写代码头秃

今日种草打卡一件办公室清爽养生饮料十分米饮品 宠粉福利店铺 :某信小程序:十分米生活馆 抖店:十分米当夏日的热浪如潮水般汹涌而来,你是否渴望一种能瞬间驱散酷暑、唤醒味蕾的神奇饮品? 今天,我要为你介绍的,就是这样一款清凉解暑的秘密武器——十分米莲藕汁宝应。 它不…

SpringBoot+mail 轻松实现各类邮件自动推送

一、简介 在实际的项目开发过程中,经常需要用到邮件通知功能。例如,通过邮箱注册,邮箱找回密码,邮箱推送报表等等,实际的应用场景非常的多。 早期的时候,为了能实现邮件的自动发送功能,通常会使用 JavaMail 相关的 api 来完成。后来 Spring 推出的 JavaMailSender 工具,…

fastjson低版本反序列化bug/设计缺陷记录

1. 问题场景 _id正常的赋值 相同的代码我们继续跑 _id的值被反序列化到id上了??? 相同的代码,跑出不一样的反序列化结果,amazing 2.问题探究 2.1 List<FieldInfo> 反序列化时会先创建一个List<FieldInfo>每一个FieldInfoList<FieldInfo>的填充方式:遍历…

编译安装Kubernetes 1.29 高可用集群(7)--Metrics Server节点监控配置

1.部署Metrics Server节点监控1.1 在任意k8s-master节点上下载Metrics Server的创建文件 https://github.com/kubernetes-sigs/metrics-server/releases wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.7.1/components.yaml 1.2 修改单机版配置…

warmup(php反序列化+SQL注入)

warmup(php反序列化+SQL注入)题目界面单看题目界面的话推测可能是SQL注入。题解 题目涉及三个附近,主要从index.php和conn.php入手。index.php中有两个功能,一个是检查请求中的Cookie,一个是检查用户提交的用户名和密码。检查Cookie 首先要求Cookie中的变量是一个数组,然后…