当前位置: 首页 > news >正文

树状数组训练题 - HDU 4217 Data Structure?

题目出处HDU 4217 Data Structure?

题意大致如下(由deepseek总结)

  • 初始有一个包含 1 到 N 的整数集合(所有数互不相同,按自然顺序)。
  • 进行 K 轮操作,第 i 轮给出一个正整数 Ki,要求在当前剩余的数字中,找到第 Ki 小的数,将它从集合中移除,并累加到答案总和中。
  • 输出所有被移除的数的总和。

首先看一下为什么这是树状数组的题目

这道题目里我们需要支持两个操作:

  1. 查询第$k_i $小的数
  2. 删除这个数

先考虑暴力求解

  • 用数组维护当前剩余的数,每次查询\(O(n)\)
  • 如果单纯数组维护,删除\(O(n)\),如果链表维护,删除\(O(1)\)
    总计时间复杂度\(O(n * k)\),在题目2.6e6的数据规模下很容易TLE

换个思路

这个时候我们需要换个思路,不能单纯地去维护当前剩余的数了。
由于我们要求的是第\(k_i\)小的数,而且给定的初始数组是天然有序的(类似std::iota生成的数组),下标与值相等
所以,若记当前的下标为x,数组为tr我们可以考虑维护tr[x]的值为小于等于x的值的个数。

再考虑使用数据结构优化

这个时候我们看到了单点查询和单点修改,只有这两个需求,而且需要降低复杂度,很容易就能想到树状数组了。

现在来看实现:

把模板中原来的前缀和与查询改成以下代码,用于查找第k小的数

i32 kth(i32 k)
{i32 idx = 0;for (i32 bit = 1 << (31 - __builtin_clz(n)); bit; bit >>= 1){i32 nxt = idx + bit;if (nxt <= n && tr[nxt] < k){k -= tr[nxt];idx = nxt;}}return idx + 1;
}

同时,初始化时,依次把所有的值都增加1,可以实现把tr数组维护成tr[i] = i - 1

for (i32 i = 1; i <= n; ++ i)bit.add(i, 1);

最后贴完整的ac代码

#include <bits/stdc++.h>
using namespace std;
using i32 = int;
using i64 = long long;struct BIT
{i32 n; vector<i64> tr;BIT(i32 n_){n = n_;tr.assign(n + 1, 0);}i64 lowbit(i32 x){return x & -x;}void add(i32 idx, i32 delta){while (idx <= n){tr[idx] += delta;idx += lowbit(idx);}}i32 kth(i32 k){i32 idx = 0;for (i32 bit = 1 << (31 - __builtin_clz(n)); bit; bit >>= 1){i32 nxt = idx + bit;if (nxt <= n && tr[nxt] < k){k -= tr[nxt];idx = nxt;}}return idx + 1;}};void solve(i32 testcase)
{i32 n, k; cin >> n >> k;BIT bit = BIT(n);for (i32 i = 1; i <= n; ++ i)bit.add(i, 1);i64 ans = 0;while (k -- ){i32 x; cin >> x;i32 val = bit.kth(x);ans += val;bit.add(val, -1);}cout << "Case " << testcase << ": " << ans << '\n'; 
}i32 main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);i32 t; cin >> t;for (i32 i = 1; i <= t; i ++ ) solve(i);return 0;
}
http://www.jsqmd.com/news/840870/

相关文章:

  • 【2026年拼多多暑期实习/春招- 5月17日-第四题- 多多的道路修建Ⅱ】(题目+思路+JavaC++Python解析+在线测试)
  • 告别命令行恐惧症:N_m3u8DL-CLI-SimpleG如何让M3U8下载变得像聊天一样简单
  • 14505黄大年茶思屋145期 第五题 面向长期运行LLM Agent的高效记忆构建和查询算法 标准化解题框架
  • ARM Cortex-A55温升实测:从热成像到散热优化的嵌入式设计实践
  • 2026 年全国天津搬家拖运物流怎么选?兴达伟业物流15022082555 - 品牌企业推荐师(官方)
  • Arm架构文档版本控制与嵌入式开发实践
  • 【NotebookLM高阶问答工作流】:从上传→切片→提问→溯源→导出,一整套可复用的SOP模板(含GTD集成方案)
  • 2026 年互联网洗衣靠谱品牌推荐:干洗 / 上门取送 / 衣物家纺洗护选择指南 - 海棠依旧大
  • 基于GCP部署开源语音数据采集站:从零构建定制化语音数据集
  • Atmel Studio 6系统内调试实战:从硬件接口到高级技巧全解析
  • 单例模式深度解析:从基础实现到生产级避坑指南
  • 深度解析REFramework架构原理与RE引擎游戏兼容性优化方案
  • 出口土耳其:关键注意事项与避坑指南
  • 边走边聊 Python 3.8:Chapter 20:测试与调试
  • 从《魔城迷踪》到3D高斯溅射:图形学中那些‘非主流’几何表达的奇妙复兴
  • 别再手动点选了!用Python脚本5分钟搞定Abaqus批量加载节点力(附完整代码)
  • java小题练习
  • 为ClaudeCode配置Taotoken作为稳定可靠的API供应商
  • Mac清理终极指南:3步彻底卸载应用残留,Pearcleaner免费开源解决方案
  • 对比自行维护多个API密钥使用Taotoken统一管理的便捷性体验
  • 基于大语言模型的AI代理:自主循环执行系统任务的技术解析与实践
  • CodexPool:基于向量语义搜索的智能代码索引与检索系统实践
  • Unity 5.6移动VR开发与单通道渲染优化指南
  • 2026嵌入式培训怎么选?一个工程师的3条硬核判断标准
  • Web架构师工具箱:从工程化实践到现代化Web开发全流程
  • 任天堂Switch模拟器终极指南:2小时从零到精通PC游戏体验
  • 5分钟快速上手Figma中文界面:设计师必备的终极汉化插件指南
  • Node.js服务端项目如何集成Taotoken管理多模型调用与成本
  • 04-内存管理
  • WeChatExporter:将你的数字记忆转化为永恒的数字档案