笔记——树状数组

news/发布时间2024/8/25 16:53:48

蓝月の笔记——树状数组

可恶的OI里,我们尝尝会遇到一些区间问题,例如区间修改单点查询,单点修改区间查询,区间修改单点查询,单点修改单点查询

其中,单点修改区间查询,就是树状数组最经典的用法啦!

Luogu - P3374

给定一个长度为 \(n\) 的序列 \(a_1,a_2,\cdots,a_n\) 和两种操作:

  1. 输入 1 x k\(a_k\) 加上 \(x\)
  2. 输入 2 l r,求 \(\sum_{i=l}^r a_i\)

这就是我们说的单点修改区间查询

根据前缀和的思想,我们可以用一些手法求出每一个 \([1,x]\) 的和。查询时直接输出 \(Q(r) - Q(l)\) 即可。(\(Q(x)\) 为查询 \(\sum_{i=1}^x a_i\) 的函数)

首先我们设树状数组的数组(?)为数组 \(c\)

定义 \(c_x\) 表示树状数组这棵树中 \(x\) 的所有子节点的 \(c_i\) 总和,即 \(c_x = \sum_{i}^{i \in \text{son of x}} c_i\)


\(\operatorname{lowbit}\)

我们引入一个函数,叫 \(\text{lowbit}\),从避免可知,\(\operatorname{lowbit}\) 就是最 \(\operatorname{low}(\texttt{低})\)\(\operatorname{bit}(\texttt{二进制位})\),即二进制中最低位的 \(1\)

举个例子:

\(\qquad\qquad\qquad\quad\downarrow\)

\(\qquad\qquad\qquad\quad\,\vdots\)

\(\because x = 18 = (10010)_2\)

\(\qquad\qquad\qquad\quad\,\vdots\)

\(\qquad\qquad\qquad\quad\uparrow\)

\(\because x = 18 = (10010)_2\)

\(\operatorname{lowbit}\) 怎么求呢,这时候就要用到补码的特性了。

我们注意到 \(x\)\((\sim{x}) + 1\) 的二进制,我们求的最低位的 \(1\) 一直到最后一位都没有变化,这一段是 \((100\cdots0)_2\),而前面的部分全部取反。

我们充分发扬人类智慧,将 \(x\)\((\sim{x}) + 1\) 按位与,就可以把前面的全部消掉,而留下 \((100\cdots0)_2\) 这一部分,而这,就是我们要求的 \(\operatorname{lowbit}\)

而根据补码的性质 \((\sim{x}) + 1 = (-x)\),所以我们可以得到求 \(\operatorname{lowbit}\) 的代码:

int L(int x) {return x & -x;
}

如果你喜欢写成宏定义的话:

#define L(x) ((x) & (-x))

还是已 \(x=18\) 为例:

\[\text{lowbit} = (10010)_2 \& (01110)_2 \]

\[\quad\,\,\,\,10010 \]

\[\&\quad01110 \]

\[\_\_\_\_\_\_\_\_\_\_ \]

\[\quad\quad\quad\,\,\,\,00010 = 2 \]

我们前面手算的也是 \(2\),这就证明了 \(\text{lowbit} = x \& -x\)


\(\operatorname{update}\)

先放图。

【图片转载自liruixiong0101的blog】

观察这棵树,可以发现 \(c_i\) 的父亲为 \(c_{i + \text{lowbit}(i)}\),而根据 \(c\) 的定义 \(c_x\) 一定在 \(c_{i + \text{lowbit}(i)}\) 里面,然后我们循环迭代递推,所以我们可以得到 \(\text{update}\) 的代码:

void U(int x, int y) {for (int i = x; i <= n; i += L(i)) {c[i] += y;}
}

\(\text{query}\)

根据设计,\(\text{query}\) 求的是 \(\sum_{i=1}^{x}a_i\) 而不是 \(\sum_{i=l}^{r}a_i\)!!!

根据定义,\(c_x\) 代表 \(\sum_{i=x - \text{lowbit}(x) + 1}^{x}a_i\),我们可以把 \(\text{query}\) 操作抽象成跳跃的过程。

我们现在 \(x\) 的位置,我们的目标是跳到 \(1\),根据 \(c\) 的定义,我们先往前跳 \(\text{lowbit}(x)\) 格,也就是跳过 \(c_x\) 管辖的区间,这时 \(ans \gets c_x\)

现在我们在 \(x-\text{lowbit}(i)\) 的位置,我们令 \(i \gets x-\text{lowbit}(i)\),我们再往前跳 \(\text{lowbit}(i)\) 格,正好跳过 \(c_i\) 的管辖区间,这时 \(ans \gets c_x + c_i\)

一直持续这个操作,直到 \(i \le 0\),我们就得到了 \([1,x]\) 之间不重不漏的区间和了。

根据思路写出代码:

int Q(int x) {int ans = 0;for (int i = x; i; i -= L(i)) {ans += c[i];}return ans;
}

然后求 \(\sum_{i=l}^{r}a_i\) 就可以很轻松了,即 Q(r) - Q(l - 1)


然后我们就可以写完这道水黄力!(喜

已用结构体封装好的代码:

// P3374
#include<bits/stdc++.h>using namespace std;const int kMaxN = 5e5 + 5;int L(int x) {return x & -x;
}struct BIT {int n, a[kMaxN], c[kMaxN];void U(int x, int y) {for (int i = x; i <= n; i += L(i)) {c[i] += y;}}int Q(int x) {int ans = 0;for (int i = x; i; i -= L(i)) {ans += c[i];}return ans;}
};int m, op, l, r;
BIT t;int main()
{cin >> t.n >> m;for (int i = 1; i <= t.n; i++) {cin >> t.a[i];t.U(i, t.a[i]);}for (; m; m--) {cin >> op >> l >> r;if(op == 1) {t.U(l, r);} else {cout << t.Q(r) - t.Q(l - 1) << '\n';}}return 0;
}

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

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

相关文章

【文化课学习笔记】【化学】选必一:化学反应速率

高中化学学习笔记:选必一化学反应速率【化学】选必一:化学反应速率 化学反应速率的相关概念及计算 概念及数学表达式概念:化学反应速率是定量描述化学反应进行快慢的物理量。通常用单位时间内反应物浓度的减小或生成物浓度的增加来表示。 数学表达式:\(v=\dfrac{\Delta c}{…

使用J4125主机搭建个人微型服务器

对于个人开发者而言,一个稳定可靠的服务器通常是不可或缺的。然而,云服务器的价格却让许多人望而却步。我曾通过白嫖阿里云服务提供给学生的六个月(?)免费公网服务器搭建WEB服务,在其已然过期许久的今天,我选择了一个经济且足够运行虚拟化的解决方案——搭载J4125的CPU小…

机器学习-周志华

第一章 绪论 机器学习: 致力于研究如何通过计算的手段,利用经验来改善系统自身的性能。在计算机系统中,“经验”通常以“数据“形式存在,因此,机器学习所研究的主要内容,是关于在计算机上从数据中产生”模型“的算法,即”学习算法“。有了学习算法,我们把经验数据提供…

Spring Boot 入门教程

大家好,我是深码青年,作为一名迄今为止已经有四年码龄的人来说,springboot已经深入了自己的脑子里面,所以借此机会,我们来仔细说一说关于springboot2.0的那些事儿 一、Spring Boot 是什么 以下截图自 [Spring Boot 官方文档](https://spring.io/projects/spring-boot &quo…

「高等数学」1.1.2 函数

函数函数的概念 定义: 设数集 \(D \subset \mathbf{R}\), 则称映射 \(f: D \rightarrow \mathbf{R}\) 为定义在 \(D\) 上的函数, 通常简记为 \[y = f(x), x \in D, \]其中 \(x\) 称为自变量, \(y\) 成为因变量, \(D\) 称为定义域, 记作 \(D_f\), 即 \(D_f = D\). 函数的定义中,…

IOI2023

IOI!来感受一下 IOI 的题目质量。 没做 T6。 CF436E Cardboard Box tag:选数问题的调整方法,贪心 考虑如果我们把一个数两个都选,那么根据简单调整法,显然不存在 \(b_i\) 比它小的数一个都没选。所以假设我们枚举选了两次的 \(b_i\) 最大的数,那么它前面都选了至少一次,…

03-共阳极数码管的静态显示

共阳数码管的静态显示由电路图可知此为共阳数码管 #include <REGX52.H>unsigned int code num[16] ={0xc0, // 0 1100 0000 0xf9, // 1 1111 1001 abged 为00xa4, // 2 1010 01000xb0,//30x99,//40x92,//50x82,//60xf8,//70x…

10.0 探索API调试事件原理

本章笔者将通过`Windows`平台下自带的调试API接口实现对特定进程的动态转存功能,首先简单介绍一下关于调试事件的相关信息,调试事件的建立需要依赖于`DEBUG_EVENT`这个特有的数据结构,该结构用于向调试器报告调试事件。当一个程序发生异常事件或者被调试器附加时,就会产生对…

实验1c语言输入输出和简单程序编写

实验任务1 1.竖直小人 源代码1 //打印一个字符小人2 3 #include <stdio.h>4 int main()5 {6 printf(" O \n");7 printf("<H>\n");8 printf("I I\n");9 printf(" O \n"); 10 printf("<H>\…

testpmd

estPMDTestPMD 的本质是一个使用 DPDK 库实现的 DPDK Application,作用是在以太网端口之间转发数据包。通过 TestPMD 运行时的命令行,我们可用于配置端口(Port)之间的数据包转发和网卡(Network Interface)支持的其他功能。此外,我们还可以用 TestPMD 来尝试一些不同的驱…

傻逼错误合计

1.多测不清空,一切等于零(2023.10.3,J组模拟,痛失100pts)

c语言代码练习2(1)

自定义摘要...#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() {int i = 1;int num = 1;int x = 0;int sum = 0;for (x = 1; x <= 10; x++){while (i <= x){num=num* i;i++;}sum += num;//将每次求的阶乘加起来}printf("while循环,1-10阶乘…

XXL-JOB简单使用

简介 XXL-JOB 是一个分布式任务调度平台,简单来说就是,我们可以用它来实现定时任务。 它有 学习简单、轻量级、易扩展、动态生效、调度中心HA、执行器HA、弹性扩容缩容、路由策略、故障转移、阻塞处理策略、任务超时控制、任务失败重试、任务失败告警、分片广播任务、动态分片…

2023/10/3软件工程日报

今天继续vue的学习,今天完成了对组件插槽的学习,贴出代码

火山引擎 ByteHouse:如何提升 18000 节点的 ClickHouse 可用性?

更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 ClickHouse 是业内被广泛使用的 OLAP 引擎。当集群规模过大时,ClickHouse 则面临使用局限性的问题。如何提升 ClickHouse 的可用性,成为困扰广大开发者的难题之一。目前,字节跳动内部…

2023.10 做题纪要 #1

2023.10 做题纪要 #1目录2023.10.2CF526G Spiders Evil PlanP3642 [APIO2016] 烟火表演P9623 [ICPC2020 Nanjing R] Babys First Suffix Array Problem2023.9.29 放假了哈哈。 然后下午去姥姥家,然后晚上看了一晚上视频,没干啥有意义事情。 2023.9.30 去姥姥家,和我表哥成功…

携程Apollo配置中心相关

使用 下载地址 数据库初始化 apolloconfigdb.sql apolloportaldb.sql 构建 先配置JDK环境变量,再配置MAVEN环境变量,MAVEN_HOME和PATH。build.bat中修改数据库地址和用户名密码,构建之后会创建jar包。通过以下命令运行 java -jar xxx.jar运行顺序为 apollo-configservice &g…

芯片制造金属化分析

芯片制造金属化分析 CMOS:标准金属化 铜金属化 连接尖峰 钛的应用 接触过程的演变 金属CVD舱室 钨籽层和大块层 CVD PVD和CVD TiN层 预清洁Ti/TiN PVD PVD固体材料CVD气体或蒸汽 热蒸发 电子束蒸发器 溅射 动量转移将使表面原子脱离直流二极管溅射 磁控溅射示意图 带护罩的PVD…
推荐文章