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

【数据结构】树状数组总结

知识概览

树状数组有两个作用:

  1. 快速求前缀和        时间复杂度O(log(n))
  2. 修改某一个数        时间复杂度O(log(n))

例题展示

1. 单点修改,区间查询

题目链接

活动 - AcWing本活动组织刷《算法竞赛进阶指南》,系统学习各种编程算法。主要面向有一定编程基础的同学。icon-default.png?t=N7T8https://www.acwing.com/problem/content/description/243/

题解

涉及单点修改和求前缀和,并且要求时间复杂度小,可以用树状数组。

代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;typedef long long LL;const int N = 200010;int n;
int a[N];
int tr[N];
int Greater[N], lower[N];int lowbit(int x)
{return x & -x;
}void add(int x, int c)
{for (int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}int sum(int x)
{int res = 0;for (int i = x; i; i -= lowbit(i)) res += tr[i];return res;
}int main()
{scanf("%d", &n);for (int i = 1; i <= n; i++) scanf("%d", &a[i]);for (int i = 1; i <= n; i++){int y = a[i];Greater[i] = sum(n) - sum(y);lower[i] = sum(y - 1);add(y, 1);  //将y加入树状数组,即数字y出现1次}memset(tr, 0, sizeof tr);LL res1 = 0, res2 = 0;for (int i = n; i; i--){int y = a[i];res1 += Greater[i] * (LL)(sum(n) - sum(y));res2 += lower[i] * (LL)(sum(y - 1));add(y, 1);  //将y加入树状数组,即数字y出现1次}printf("%lld %lld\n", res1, res2);return 0;
}

2.区间修改,单点查询

题目链接

活动 - AcWing本活动组织刷《算法竞赛进阶指南》,系统学习各种编程算法。主要面向有一定编程基础的同学。icon-default.png?t=N7T8https://www.acwing.com/problem/content/248/

题解

需要用到差分数组,区间修改可以转化成对差分数组的单点修改,单点查询可以转化成对差分数组求前缀和,这样就可以转化成经典的树状数组操作。

代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;typedef long long LL;const int N = 100010;int n, m;
int a[N];
LL tr[N];int lowbit(int x)
{return x & -x;
}void add(int x, int c)
{for (int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}LL sum(int x)
{LL res = 0;for (int i = x; i; i -= lowbit(i)) res += tr[i];return res;
}int main()
{scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++) scanf("%d", &a[i]);for (int i = 1; i <= n; i++) add(i, a[i] - a[i - 1]);while (m--){char op[2];int l, r, d;scanf("%s%d", op, &l);if (*op == 'C'){scanf("%d%d", &r, &d);add(l, d), add(r + 1, -d);}else{printf("%lld\n", sum(l));}}return 0;
}

参考资料

  1. AcWing算法提高课

相关文章:

  • 推荐一款好用的包含表格识别的OCR网站
  • Debian系统安装OpenVPN
  • javaWebssh汽车销售管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计
  • Flink系列之:窗口关联
  • HTML面试题
  • 【Spark面试】Spark面试题答案
  • 修改npm源码解决服务端渲染环境中localstorage报错read properties of undefined (reading getItem)
  • Oracle-应用会话集中在RAC集群一个节点问题
  • 使用 ?? 重新定义逻辑以获得更严格、更安全的 JavaScript 默认值
  • Vue中的数据变化监控与响应——深入理解Watchers
  • 数据分析为何要学统计学(10)——如何进行比率检验
  • 【jmeter】接口测试流程
  • 阿里云部署k8s with kubesphere
  • PMP项目管理 - 资源管理
  • Python Django 连接 PostgreSQL 操作实例
  • CentOS从零开始部署Nodejs项目
  • codis proxy处理流程
  • Docker入门(二) - Dockerfile
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • laravel5.5 视图共享数据
  • SwizzleMethod 黑魔法
  • 翻译:Hystrix - How To Use
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • ------- 计算机网络基础
  • 码农张的Bug人生 - 见面之礼
  • 前端临床手札——文件上传
  • 世界上最简单的无等待算法(getAndIncrement)
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 移动端 h5开发相关内容总结(三)
  • 原生Ajax
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • 正则表达式
  • Java数据解析之JSON
  • ​渐进式Web应用PWA的未来
  • #每日一题合集#牛客JZ23-JZ33
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第1节 (全局数据、栈和堆)
  • (Python第六天)文件处理
  • (二)linux使用docker容器运行mysql
  • (附源码)ssm高校实验室 毕业设计 800008
  • (理论篇)httpmoudle和httphandler一览
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • .aanva
  • .NET 常见的偏门问题
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径
  • .net 托管代码与非托管代码
  • .NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke(转)
  • .NET技术成长路线架构图
  • .Net中间语言BeforeFieldInit
  • .net中生成excel后调整宽度
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [④ADRV902x]: Digital Filter Configuration(发射端)