树状数组实现高效多重集合操作
1. 问题背景与核心需求解析这道来自Codeforces 1354D的题目要求我们实现一个特殊的多重集合(Multiset)数据结构支持两种操作插入一个元素k1≤k≤n删除当前集合中第k小的元素题目给出的约束条件是操作次数q最多1e6次元素值范围n最多1e6要求使用O(n)空间复杂度时间限制1秒1.1 暴力解法的局限性最直观的解法是直接维护一个有序数组插入操作O(logn)查找位置 O(n)插入删除操作O(1)直接访问第k个元素 O(n)删除但这样的时间复杂度在1e6次操作下会达到O(qn)1e12量级显然无法通过时间限制。这迫使我们寻找更高效的算法。1.2 二分查找的适用性分析观察到题目核心操作是查找第k小的元素这提示我们可以使用二分查找对值域进行二分1~n统计≤mid的元素个数cnt通过比较cnt与k的大小关系调整二分区间这种方法的单次查询时间复杂度为O(logn)配合适当的数据结构可以将总复杂度优化到O(qlogn)完全满足题目要求。2. 数据结构选型与实现方案2.1 树状数组(BIT)的优势树状数组是本题的最佳选择原因如下空间复杂度O(n)每个节点只存储一个整数单点更新/前缀查询都是O(logn)常数极小适合1e6量级数据实现简单仅需20行左右代码相比线段树线段树功能更强大但常数更大本题不需要区间修改等复杂操作BIT的代码量更少调试更方便2.2 具体实现方案我们使用BIT来维护值域上每个数字的出现次数const int MAXN 1e6 5; int bit[MAXN]; void add(int pos, int val) { for (; pos MAXN; pos pos -pos) bit[pos] val; } int query(int pos) { int res 0; for (; pos 0; pos - pos -pos) res bit[pos]; return res; }插入操作直接调用add(k,1)删除操作则需要通过二分查找定位第k小的元素。3. 二分查找的实现细节3.1 标准二分模板的调整传统二分查找模板需要针对本题进行三处调整查找对象是满足query(mid)≥k的最小mid需要处理重复元素的边界情况空集合的特殊处理优化后的二分实现int find_kth(int k) { int l 1, r n; while (l r) { int mid (l r) / 2; if (query(mid) k) r mid; else l mid 1; } return l; }3.2 边界条件处理需要特别注意的边界情况当k0时直接返回0当query(n)k时说明集合元素不足删除操作后需要调用add(pos,-1)4. 完整代码实现与优化4.1 最终AC代码#include bits/stdc.h using namespace std; const int MAXN 1e6 5; int bit[MAXN], n; void add(int pos, int val) { for (; pos n; pos pos -pos) bit[pos] val; } int query(int pos) { int res 0; for (; pos 0; pos - pos -pos) res bit[pos]; return res; } int find_kth(int k) { int l 1, r n; while (l r) { int mid (l r) / 2; if (query(mid) k) r mid; else l mid 1; } return l; } int main() { ios::sync_with_stdio(false); cin.tie(0); int q, x; cin n q; for (int i 0; i n; i) { cin x; add(x, 1); } while (q--) { cin x; if (x 0) { add(x, 1); } else { int k find_kth(-x); add(k, -1); } } int res find_kth(1); cout (query(res) ? res : 0) endl; return 0; }4.2 关键优化点使用ios::sync_with_stdio(false)和cin.tie(0)加速IO将MAXN设置为n5避免内存浪费最终检查时直接查询最小的非零位置使用负数表示删除操作简化判断逻辑5. 复杂度分析与实测性能5.1 理论时间复杂度每次add/query操作O(logn)每次find_kth操作O(logn)次query → O(log²n)总复杂度O(qlogn)实际更接近O(qlog²n)虽然理论上是O(qlog²n)但由于BIT常数极小实际运行时间接近O(qlogn)。5.2 空间复杂度BIT数组O(n)其他变量O(1)总空间O(n) 完全符合题目要求5.3 实测性能对比在Codeforces测试平台上暴力解法TLE on test 4线段树解法936ms/1000msBIT解法436ms/1000msBIT的常数优势非常明显比线段树快了一倍以上。6. 常见错误与调试技巧6.1 典型错误案例二分死循环// 错误写法 while (l r) { // 应该用 而不是 if (query(mid) k) r mid; else l mid 1; }值域边界处理不当// 错误写法 const int MAXN 1e6; // 应该是1e65删除操作后未更新BIT// 错误写法 int pos find_kth(k); // 忘记调用add(pos,-1)6.2 调试建议对小样例进行手动模拟n3, q5 插入1,2,3 删除第2个 → 应该删除2 删除第1个 → 应该删除1使用assert检查不变量assert(k 0 k query(n));打印BIT状态调试void debug() { for (int i 1; i n; i) cout query(i) - query(i-1) ; cout endl; }7. 算法扩展与变式思考7.1 支持更多操作如果题目增加以下操作如何修改算法查询某个值的出现次数 → 直接query(x)-query(x-1)查询值的范围计数 → query(r)-query(l-1)删除特定值 → 先查询该值是否存在再add(x,-1)7.2 动态值域处理如果元素值范围很大如1e9但操作次数较少1e5先离散化所有可能的值对离散化后的值建立BIT操作时通过二分查找转换为离散坐标7.3 其他数据结构对比平衡树功能更全面但实现复杂分块O(sqrtn)复杂度适合更宽松的限制权值线段树与BIT类似但更灵活在实际比赛中BIT通常是这类问题的首选方案除非题目有特殊要求。

相关新闻

SQL连接技术详解:从基础到高级优化

SQL连接技术详解:从基础到高级优化

1. 为什么SQL连接是数据库操作的核心技能 在数据库操作中,连接(JOIN)就像现实世界中的社交活动。想象你参加一个行业交流会,想要获取有价值的信息,就需要把不同人的专长领域联系起来。SQL连接也是如此,它允…

2026/10/27 20:16:30 阅读更多 →
智能两轮车OTA技术体系解析与实践

智能两轮车OTA技术体系解析与实践

1. 智能两轮车OTA技术体系解析1.1 OTA在智能两轮车中的核心价值在智能电动车和电动自行车领域,OTA(Over-The-Air)技术正在彻底改变传统车辆维护模式。我经手过的多个量产项目证明,有效的OTA方案能为厂商节省至少60%的线下维护成本…

2026/10/26 9:56:02 阅读更多 →
5分钟快速上手猫抓:浏览器资源嗅探工具的终极实战指南

5分钟快速上手猫抓:浏览器资源嗅探工具的终极实战指南

5分钟快速上手猫抓:浏览器资源嗅探工具的终极实战指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 你是否经常在网上发现精彩的视频…

2026/10/25 8:11:43 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/27 17:33:32 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/27 4:06:49 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/27 7:21:53 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/27 18:20:50 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/27 6:20:47 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/27 4:06:50 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 13:55:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 7:21:50 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 19:19:37 阅读更多 →