浅谈压位 trie 及其简单应用

Update on 2026.1.23:修改了一些错误。

突然想写就写了。

功能

可以在 \(O(\log_w{V})\)\(w\) 为计算机位长,通常取 \(32\)\(64\))的时间复杂度、\(O(\frac{V}{w})\) 的空间复杂度下完成以下操作:

  • 插入一个不存在的数或删除一个数;

  • 查询最小或最大值;

  • 查询前驱后继。

正常用 01trie 只能做到 \(O(\log_2{V})\),因为它是一个 \(2\) 叉树。我们发现每个位置只用存 \(0/1\),我们直接分 \(w\) 叉不就优完了?

实现

插入删除是好做的,查询最小最大值的话用 __builtin_ctz__builtin_clz 稍微处理一下就可以了。查询前驱后继的话,跟正常的平衡树一样:我们从叶子结点往根跑,查询一下有没有比它大或小的兄弟,然后再在这里面查询最小或最大值即可。

以下是对于 \(V=2^{20}\) 的压位 trie 代码(直接展开写的,常数会小一些):

struct trie{#define ctz(x) __builtin_ctz(x)#define clz(x) __builtin_clz(x)int ans;unsigned int a0,a1[1<<5],a2[1<<10],a3[1<<15],ak;inline void ins(const int x)noexcept{a0|=1u<<(x>>15),a1[x>>15]|=1u<<((x>>10)&31),a2[x>>10]|=1u<<((x>>5)&31),a3[x>>5]|=1u<<(x&31);}inline void era(const int x)noexcept{(a3[x>>5]&=~(1u<<(x&31)))?(1):((a2[x>>10]&=~(1u<<((x>>5)&31)))?(1):((a1[x>>15]&=~(1u<<((x>>10)&31)))?(1):(a0&=~(1u<<(x>>15)))));}inline bool have(const int x)noexcept{return (a3[x>>5]>>(x&31))&1;}inline int minn()noexcept{return a0?(ans=ctz(a0),ans=(ans<<5)|ctz(a1[ans]),ans=(ans<<5)|ctz(a2[ans]),(ans<<5)|ctz(a3[ans])):(1<<20);}inline int maxn()noexcept{return a0?(ans=31^clz(a0),ans=(ans<<5)|(31^clz(a1[ans])),ans=(ans<<5)|(31^clz(a2[ans])),(ans<<5)|(31^clz(a3[ans]))):(0);}inline int suf(const int x)noexcept{if((ak=(a3[x>>5]>>(x&31))>>1)){return(x&~31u)|((x&31)+1+ctz(ak));}if((ak=(a2[x>>10]>>((x>>5)&31))>>1)){return ans=((x>>5)&~31u)|(((x>>5)&31)+1+ctz(ak)),(ans<<5)|ctz(a3[ans]);}if((ak=(a1[x>>15]>>((x>>10)&31))>>1)){return ans=((x>>10)&~31u)|(((x>>10)&31)+1+ctz(ak)),ans=(ans<<5)|ctz(a2[ans]),(ans<<5)|ctz(a3[ans]);}if((ak=a0>>(x>>15)>>1)){return ans=((x>>15)&~31u)|(((x>>15)&31)+1+ctz(ak)),ans=(ans<<5)|ctz(a1[ans]),ans=(ans<<5)|ctz(a2[ans]),(ans<<5)|ctz(a3[ans]);}return x;}inline int pre(const int x)noexcept{if((ak=a3[x>>5]&((1u<<(x&31))-1))){return(x&~31u)|(31^clz(ak));}if((ak=a2[x>>10]&((1u<<((x>>5)&31))-1))){return ans=((x>>5)&~31u)|(31^clz(ak)),(ans<<5)|(31^clz(a3[ans]));}if((ak=a1[x>>15]&((1u<<((x>>10)&31))-1))){return ans=((x>>10)&~31u)|(31^clz(ak)),ans=(ans<<5)|(31^clz(a2[ans])),(ans<<5)|(31^clz(a3[ans]));}if((ak=a0&((1u<<(x>>15))-1))){return ans=((x>>15)&~31u)|(31^clz(ak)),ans=(ans<<5)|(31^clz(a1[ans])),ans=(ans<<5)|(31^clz(a2[ans])),(ans<<5)|(31^clz(a3[ans]));}return x;}
};

动态开点的话就把上面的数组改成 unordered_map 即可,空间复杂度就是 \(\min(n\log_wV,\frac{V}{w})\)

对比

可能很多人对 \(O(\log_{w}{V})\) 没什么概念,其实就是 \(O(\log_{2}{V})\) 优化了 \(\frac{1}{5}\)\(\frac{1}{6}\),通常可以看成一个 \(4\)\(5\) 的常数。

应用

由于题目中往往可以有重复元素,所以使用压位 trie 前经常得用离散化。

以 P3378 【模板】堆 为例,可以先用基数排序让每个值互不相同然后再用压位 trie 做到 \(O(n\log_{w}n)\)

trie t;
unsigned bucket[256];
#define SORTBYTE(TYPE, FR, TO, LEN, BIT) {\memset(bucket, 0, sizeof(bucket));\for (TYPE *it = (FR) + LEN; it != (FR); it--)\++bucket[(it[-1].x >> BIT) & 255];\for (unsigned *it = bucket; it != bucket + 255; it++)\it[1] += it[0];\for (TYPE *it = (FR) + LEN; it != (FR); it--)\(TO)[--bucket[(it[-1].x >> BIT) & 255]] = it[-1];\
}
constexpr int N=1e6+5;
struct node{int id,x;}q[N],st[N],st2[N];int n,top;
int main(){cin>>n;for(int i=1;i<=n;++i)cin>>q[i].id,(q[i].id==1)?(cin>>q[i].x,st2[top++]={i,q[i].x}):(node{});SORTBYTE(node,st2,st,top, 0);SORTBYTE(node,st,st2,top, 8);SORTBYTE(node,st2,st,top,16);SORTBYTE(node,st,st2,top,24);SORTBYTE(node,st2,st,top,30);for(int i=0;i<top;++i)q[st[i].id].x=i;for(int i=1;i<=n;++i){switch(q[i].id){case 1:t.ins(q[i].x);break;case 2:cout<<st[t.minn()].x<<'\n';break;case 3:t.era(t.minn());break;}}return 0;
}

跑得有点慢,用了 \(200\) 多毫秒。

经常很多分块题你只能想到甚至只能做到类似于 \(O(n\sqrt{n\log_2n})\) 的东西,用上压位 trie 你就可以强行创过去或抢到最优解(例如 P8078 [WC2022] 秃子酋长 就可以拿 \(n\sqrt{n}\log_wn\) 应创,并且卡不掉)。

众所周知,正常的珂朵莉树区间赋值单点查用 set 只能在非随机数据下做到 \(O(n\log_2n)\),但是不难发现这其实每次都是在插入删除或求前驱后继,直接上压位 trie 就可以做到 \(O(n\log_{w}n)\)(使用 Veb 可以做到严格 \(O(n\log_2\log_2n)\))。

以 P13983数列分块入门8 为例,当其他人在使用 \(O(n\log_{2}n)\) 的 set 维护珂朵莉树时,你可以直接悄悄地交一发 \(O(n\log_{w}n)\) 的压位 trie 并成功得到最优解。

trie t;
constexpr int N=3e5+5;
int n,m;
int nxt[N],val[N],ans;
inline void split(int l)
{if(t.have(l))return;int pr=t.pre(l);t.ins(l);nxt[l]=nxt[pr],val[l]=val[pr],nxt[pr]=l;
}
int main(){cin>>n;t.ins(n+1);for(int i=1;i<=n;++i)nxt[i]=i+1,cin>>val[i],t.ins(i);int l,r,v,ll,su;for(int i=1;i<=n;++i){cin>>l>>r>>v;ans=0;split(ll=l),split(++r);do{(val[ll]==v)?(su=nxt[ll],t.era(su),ans+=su-ll,ll=su):(su=nxt[ll],t.era(su),ll=su);}while(ll!=r);nxt[l]=r,val[l]=v,t.ins(r);cout<<ans<<'\n';}return 0;
}

还有就是:两个 01trie 进行位运算的复杂度跟 bitset 复杂度是一样的,例题待补。

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

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

相关文章

同样能做采集控制,ARM边缘AI控制器与PLC究竟区别在哪里?

在工业自动化的世界里,PLC几乎是“稳如老狗”的存在。几十年来,它承担着生产线的逻辑控制、IO采集、实时执行,可靠性经过无数工厂验证。但这两年,个新角色迅速出圈——ARM边缘AI控制器。它不仅能采集、能控制,还能…

2026年目前优秀的纹路袋制造厂排行榜,自立袋/三边封拉链袋/聚酯尼龙袋/中封袋/纹路袋/自立拉链袋,纹路袋制造商如何选

在塑料包装行业,纹路袋作为保障产品运输安全、提升品牌展示效果的核心载体,其质量与适配性直接影响下游企业的市场竞争力。河北墨胶红塑业有限公司凭借“定制灵活、交付高效、成本可控”的核心优势,成为华北地区乃至…

2026年,银川哪家化妆学校靠谱?化妆培训,彩妆培训,美业培训,深度指南帮你精准避坑

2026年,银川哪家化妆学校靠谱?化妆培训,彩妆培训,美业培训,深度指南帮你精准避坑 想入行美业、学一门硬核化妆手艺,却被银川五花八门的化妆培训学校绕晕?担心交了学费学不到真技术?害怕“包就业”是噱头、“终…

【SQL注入防护】避开这些坑!程序员必知的5种参数化查询与代码安全实践

SQL注入详解 什么是SQL注入&#xff1f; SQL注入是一种将恶意SQL代码插入到应用程序输入参数中的攻击技术&#xff0c;攻击成功后可以获取、篡改或删除数据库数据&#xff0c;甚至控制数据库服务器。 攻击原理 -- 正常查询语句 SELECT * FROM users WHERE username [输入1…

人事考试安全风险点防控管理信息系统

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 系统主要功能包括&#xff1a; 1、基本信息&#xff0c;考试过程中流程发布。包括工作流程、工作内容、安全风险点、防范和控制措施。 2、考试管理&#xff0c;考试信息添加、编辑、…

开发超市囤货最优解程序,输入常买商品,保质期。家庭月消耗量,结合超市促销信息,计算囤货数量和最佳囤货时间,避免过期浪费。

1. 实际应用场景与痛点 场景 - 家庭每月固定采购米、面、油、牛奶、鸡蛋等易耗品 - 超市经常有不同商品的促销活动&#xff08;打折、买一送一、满减&#xff09; - 商品有不同保质期&#xff0c;囤多了会过期浪费 - 想在保证不断货的前提下&#xff0c;最大化利用促销节省开…

10款AI论文写作工具,满足数学建模论文复现与排版需求

数学建模论文的复现与排版往往时间紧迫、任务繁重&#xff0c;但借助AI工具可以显著提升效率。通过对10款热门AI论文写作工具的评测&#xff0c;发现部分工具能自动优化公式排版、生成代码框架&#xff0c;甚至辅助模型复现&#xff0c;尤其适合需要快速完成高质量论文的场景。…

开发拼单凑单计算器,输入商品单价,满减门槛,拼单人数,自动计算每人需付金额,最优凑单商品,避免为凑单多买无用物品。

1. 实际应用场景与痛点 场景 - 电商平台常有“满 200 减 50”等满减活动 - 朋友或同事一起拼单&#xff0c;想达到满减门槛&#xff0c;但每个人只想买自己需要的商品 - 为了凑单可能被迫多买不需要的东西&#xff0c;造成浪费 - 需要公平分摊优惠金额 痛点 - 手动计算凑单组…

中国采招网API

中国采招网 API 是其旗下 “采招大数据” 的核心数据接口服务&#xff0c;采用 RESTful 架构&#xff0c;以 JSON/XML 返回结构化招投标数据&#xff0c;支持对接 CRM、BI 或自研系统&#xff0c;适用于商机挖掘、竞品监测与合规审计等场景。以下是可直接落地的核心信息与接入指…

数学建模论文如何高效复现?10个AI写作工具助你一臂之力

数学建模论文的复现与排版往往时间紧迫、任务繁重&#xff0c;但借助AI工具可以显著提升效率。通过对10款热门AI论文写作工具的评测&#xff0c;发现部分工具能自动优化公式排版、生成代码框架&#xff0c;甚至辅助模型复现&#xff0c;尤其适合需要快速完成高质量论文的场景。…

10个AI工具帮你轻松完成数学建模论文的复现与排版

数学建模论文的复现与排版往往时间紧迫、任务繁重&#xff0c;但借助AI工具可以显著提升效率。通过对10款热门AI论文写作工具的评测&#xff0c;发现部分工具能自动优化公式排版、生成代码框架&#xff0c;甚至辅助模型复现&#xff0c;尤其适合需要快速完成高质量论文的场景。…

数学建模论文如何高效排版?10个AI写作工具值得一试

数学建模论文的复现与排版常面临时间紧张、工作量大的挑战&#xff0c;而AI工具的介入能大幅提升效率。评测显示&#xff0c;部分先进的AI写作工具具备自动化公式排版优化、代码框架生成及模型复现辅助功能&#xff0c;特别适用于对论文质量和交付速度要求较高的场景。这些工具…

10个AI论文写作工具盘点,适用于数学建模论文复现与排版

AI技术为数学建模论文的复现与排版提供了高效解决方案&#xff0c;多款热门工具在评测中展现出强大的自动化能力&#xff0c;包括智能公式排版、代码框架生成和模型复现辅助功能&#xff0c;大幅缩短论文产出周期。这些工具尤其擅长LaTeX兼容处理、算法逻辑转换及数据可视化生成…

10款AI论文写作工具,优化数学建模论文的复现与排版流程

数学建模论文的高效复现与排版可借助AI工具实现质的飞跃&#xff0c;经评测显示&#xff0c;当前主流AI写作工具不仅能自动处理LaTeX公式排版、构建代码框架&#xff0c;还能辅助模型复现&#xff0c;特别适合时间紧迫的论文场景。这些工具在算法逻辑转换、可视化生成及LaTeX兼…

数学建模论文复现困难?10款AI写作工具帮你轻松搞定

数学建模论文的复现与排版往往时间紧迫、任务繁重&#xff0c;但借助AI工具可以显著提升效率。通过对10款热门AI论文写作工具的评测&#xff0c;发现部分工具能自动优化公式排版、生成代码框架&#xff0c;甚至辅助模型复现&#xff0c;尤其适合需要快速完成高质量论文的场景。…

《AI元人文:悟空而行——智能时代的价值决断与合法性重建》的参考文献

《AI元人文&#xff1a;悟空而行——智能时代的价值决断与合法性重建》的参考文献 尊敬的读者&#xff1a; 本文《AI元人文&#xff1a;悟空而行——智能时代的价值决断与合法性重建》的参考文献部分&#xff0c;是基于对原文PDF版本&#xff08;共41页&#xff0c;44713字&…

RHCSA结课考试

一&#xff0e;系统基础配置1. 关闭防火墙并禁止开机启动2. 修改主机名3. 配置本地光盘为yum源mount /dev/sr0 /mnt vim /etc/yum.repos.d/yum.repo yum clean allyum makecache4. 测试网络连通性二.部署LNMP环境 、Discuz论坛1. 安装PHP:dnf install -y php*2. 安装Nginx:dnf…

地道螺蛳粉加盟品牌怎么选择,这些要点要知道

在餐饮创业的浪潮中,一碗地道的螺蛳粉不仅是味蕾的盛宴,更是撬动财富的钥匙。面对市场上琳琅满目的螺蛳粉加盟品牌,如何找到既正宗又靠谱的合作伙伴?以下依据品牌实力、扶持政策与市场口碑,为你梳理值得关注的地道…

Java毕设选题推荐:基于springboot的交通安全案例知识学习网站【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

计算机Java毕设实战-基于springboot+vue的交通安全知识学习平台【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…