【算法】树状数组维护总结

2023-11-11

本文仅对树状数组的使用作一个总结,并非讲解。

这里的操作都对长度为 n n n 的数组 a a a 进行操作。

单点修改,区间查询

  • 暴力做法:

    • 修改: a [ x ] = y a[x]=y a[x]=y,时间复杂度为 O ( 1 ) O(1) O(1)
    • 查询: ∑ i = l r a [ i ] \sum\limits_{i=l}^ra[i] i=lra[i] ,时间复杂度为 O ( n ) O(n) O(n)
  • 树状数组:
    t r tr tr 数组 对 a a a 数组进行维护

    • 修改:

      void update(int x, int y) {
      	while (x <= n) tr[x] += y, x += (x & (-x));
      }
      
      update(x, y);
      

      时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

    • 查询:

      int query(int x) {
      	int ans = 0;
      	while (x >= 1) ans += tr[x], x -= (x & (-x));
      	return ans;
      }
      

      时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

区间修改,单点查询

  • 暴力做法:

    • 修改: a [ l ] = a [ l ] + x , ⋯   , a [ r ] = a [ r ] + x a[l]=a[l]+x,\cdots,a[r]=a[r]+x a[l]=a[l]+x,,a[r]=a[r]+x,时间复杂度为 O ( n ) O(n) O(n)
    • 查询: a [ x ] a[x] a[x],时间复杂度为 O ( 1 ) O(1) O(1)
  • 树状数组:
    b b b 数组是 a a a 的差分数组。 t r tr tr 数组对 b b b 数组进行维护

    • 修改:
      void update(int x, int y) {
      	while (x <= n) tr[x] += y, x += (x & (-x));
      }
      
      update(l, x);
      update(r + 1, -x);
      
      时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)
    • 查询:
      int query(int x) {
      	int ans = 0;
      	while (x >= 1) ans += tr[x], x -= (x & (-x));
      	return ans;
      }
      
      query(x);
      
      时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

区间修改,区间查询

区间查询的的公式为: ∑ i = l r a [ i ] \sum\limits_{i=l}^ra[i] i=lra[i],我们先考虑如何求 ∑ i = 1 p a [ i ] \sum\limits_{i=1}^p a[i] i=1pa[i]

问题转换为如何去求解这个公式,暴力情况下,求 a [ i ] a[i] a[i] O ( log ⁡ n ) O(\log n) O(logn),总时间复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn)

但是我们可以拆分这个公式:
∑ i = 1 p a [ i ] = ∑ i = 1 p ∑ j = 1 i b [ j ] = p × b [ 1 ] + ( p − 1 ) × b [ 2 ] + ⋯ + 1 × b [ p ] = ( ( p + 1 ) × ∑ i = 1 p b [ i ] ) − ( 1 × b [ 1 ] + 2 × b [ 2 ] + ⋯ + p × b [ p ] ) \begin{aligned} \sum\limits_{i=1}^p a[i] &=\sum\limits_{i=1}^p \sum\limits_{j=1}^ib[j] \\ &= p \times b[1]+(p-1)\times b[2]+\cdots+1\times b[p] \\ &= ((p+1)\times \sum\limits_{i=1}^p b[i])-(1\times b[1]+2\times b[2]+\cdots+p\times b[p])\\ \end{aligned} i=1pa[i]=i=1pj=1ib[j]=p×b[1]+(p1)×b[2]++1×b[p]=((p+1)×i=1pb[i])(1×b[1]+2×b[2]++p×b[p])

所以我们再用一个额外的树状数组去维护 i × b [ i ] i\times b[i] i×b[i] 即可。

// 区间修改[x, n]
const int N =100010;
int tr1[N], tr2[N];
void update(int x, int y) {
	int val2 = x * y;
	while (x <= n) {
		tr1[x] += y;
		tr2[x] += val2;
		x += (x & (-x));
	}
}
update(l, d);      // a[l, n] += d;
update(r + 1, -d); // a[r + 1, n] -= d

// 区间查询(1, x)
int query(int x) {
	int p = x;
	int val1 = 0, val2 = 0;
	while (x >= 1) {
		val1 += tr1[x];
		val2 += tr2[x];
		x -= (x & -x);
	}
	return (p + 1) * val1 - val2;
}
// 查询 a[l, r]
query(1, r) - query(1, l - 1);

时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【算法】树状数组维护总结 的相关文章

  • 已安装 MySQL,但执行 mysql 命令提示命令找不到!

    因个人需要 在阿里购买了一个轻量应用服务器 服务器配好 LAMP 环境 但奇怪是的我想登录 MySql 却提示命令找不到 查看 MySQL 运行状态 却是 Active running 提交了阿里工单 可是感觉客服是答非所问 我也是很无奈

随机推荐

  • Windows Terminal 和 WSL 安装及配置

    一 打开开发者选项和传递优化 二 在Microsoft Store安装Windows Terminal和Ubuntu子系统 三 配置 Windows Terminal配置 打开settings json配置文件 修改如下 此项用来配置打开W
  • 重磅!瞄准 Web 3.0,谷歌云推出专为区块链服务的 Blockchain Node Engine!

    本文由 Cloud Ace 整理发布 更多内容请访问 Cloud Ace 官网 区块链技术正在为世界各地的消费者和企业带来巨大的创新和价值创造 随着技术变得越来越主流 公司需要可扩展 安全和可持续的基础设施来发展业务并支持他们的网络 谷歌云
  • LeetCode-1124. 表现良好的最长时间段【哈希表,前缀和,单调栈】

    LeetCode 1124 表现良好的最长时间段 哈希表 前缀和 单调栈 题目描述 解题思路一 查字典 cur是当前的前缀和 劳累与不劳累天数之差 向前遍历 有两种情况 情况一 若cur大于0则是 0 i 的劳累与不劳累天数之差一定最大 记
  • Angular知识整合一:Angular中的组件和一些基本概念

    什么是Angular Angular是一个基于TypeScript构建的开发平台 它包括一下三个部分 一个基于组件的库 一组涵盖路由 表单管理 客户端服务端通信等各种功能继承的库 一套开发 构建 测试 更新代码的工具 Angular中的知识
  • matlab练习程序(渲染三原色)

    这里我用的空间是x向右为正 y向下为正 z向屏幕里面为正 相当于标准右手系绕x轴旋转了180度 将三个点光源放在 r 0 3 0 0 5 g 0 3 0 5 cos pi 6 0 5 sin pi 6 b 0 3 0 5 cos pi 6
  • 练习-Java继承和多态之接口

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 题目 任务 编写一个学校接待方面的程序 招待不同身份的人的食宿问题 编程要求 仔细阅读右侧编辑区内给出的代码框架及注释 在 Begin End 中编写一个学校接待方面的程序
  • 什么是电力系统的功率平衡?为什么在任何时候要保持电力系统的功率平衡?

    什么是电力系统的功率平衡 为什么在任何时候要保持电力系统的功率平衡 答 电力系统的功率平衡是指电力有功功率和无功功率的平衡 这种功率平衡也就是电力供需平衡 要求电力系统发送的功率与系统的负荷需要随时保持平衡 电能的一个最重要特点就是不能储存
  • 关于Vue.js中数据模型的绑定以及方法事件的绑定与调用

    在vue js中 我们可以将事件方法写在methods属性中 数据模型在data中定义 Vue的基本结构如下 只写最常用的 将数据与vue实例绑定通过v bind标签 这里绑定的是sourceId这个值 基于vue的双向绑定 如果要取vue
  • 蓝桥杯:整除序列

    整除序列 15分 题目描述 有一个序列 序列的第一个数是 n 后面的每个数是前一个数整除 2 请输出这个序列中值为正数的项 输入格式 输入一行包含一个整数 n 输出格式 输出一行 包含多个整数 相邻的整数之间用一个空格分隔 表示答案 评测用
  • 虚拟环境安装和操作

    文章目录 安装相应库和配置 查看已安装虚拟环境 创建虚拟环境 切换 进入虚拟环境 退出虚拟环境 虚拟环境 linux创建Python虚拟环境及配置 Django Flask项目中如何创建Python虚拟环境呢 汇总 环境迁移 安装相应库和配
  • 攻防世界MISC刷题1-50

    目录 1 ext3 2 base64stego 3 功夫再高也怕菜刀 4 easycap 5 reverseMe 6 Hear with your Eyes 7 What is this 8 normal png 9 something i
  • idea 添加 VUE 的语法支持和开发

    一 VUE的开发分两种 一种是直接在HTML文件中使用 一种是VUE文件的形式开发 1 首先我们先让 HTML 文件支持 VUE 的语法指令提示 2 File gt Setting gt Edit gt Inspections gt htm
  • 父类A a = new 子类B

    父类名 a new 子类名 子类名 b new 子类名 比较上面两种创建实例的区别 a只能调用父类的函数 和子类重写父类的方法 不能调用父类中不存在的子类的函数 因为它没有继承 a是父类的引用 指向了一个子类对象 好处如果一旦发现该B对象无
  • Jetson Orin NX install Fastdeploy

    FastDeploy jetson md at develop PaddlePaddle FastDeploy GitHub sudo apt get install gcc sudo apt get install cmake git c
  • postman-token的作用

    Postman生成的代码中的postman token是什么 What is the postman token in generated code from Postman 这主要用于绕过Chrome 等其他浏览器 中的错误 如果XMLH
  • QEMU/KVM PCI Passthrough(i350) & DPDK 网络性能测试

    QEMU KVM PCI Passthrough i350 DPDK 网络性能测试 硬件要求 CPU必须支持硬件虚拟化 Intel VT d or AMD Vi 和 IOMMU 原图链接 主机配置 设置iommu IOMMU kernel
  • kmp算法(最简单最直观的理解,看完包会)

    本文将以特殊的方式来让人们更好地理解kmp算法 不包括kmp算法的推导 接下来 我们将从朴素算法出发 在这之前 我们先设主串为S 模式串为T 我们要解决的询问是主串中是否包含模式串 即T是否为S的子串 版权声明 本文为原创文章 转载请标明出
  • c++ 继承 学习总结1 继承的基本语法

    前言 继承的作用是减少程序中重复的代码段 如果程序中有很多重复的代码段 可以考虑一下能否使用继承 继承的语法 class 子类 继承方式 父类 include
  • 特征提取-特征工程

    目录 1 定义 2 字典特征提取 3 英文 本特征提取 4 中文 本特征提取 1 定义 将任意数据 如 本或图像 转换为可 于机器学习的数字特征 2 字典特征提取 from sklearn feature extraction import
  • 【算法】树状数组维护总结

    本文仅对树状数组的使用作一个总结 并非讲解 这里的操作都对长度为 n n n 的数组 a a a 进行操作 单点修改 区间查询 暴力做法 修改