树状数组(Binary Indexed Tree, BIT)

树状数组(Binary Indexed Tree, BIT)

树状数组(Binary Indexed Tree, BIT),也称为 Fenwick Tree,是一种用于高效处理数组前缀和查询和单点更新的数据结构。它能够在 (O(\log n)) 时间内完成单点更新和前缀和查询操作。

基本概念

  1. 前缀和:给定一个数组 a,前缀和 prefix_sum[i] 表示 a[0] + a[1] + ... + a[i]
  2. 单点更新:更新数组 a 中的某个元素 a[i]

树状数组的结构

树状数组通过一种特殊的方式组织数组元素,使得前缀和查询和单点更新都能高效进行。具体来说,树状数组 bit 是一个与原数组 a 大小相同的数组,但它的每个元素 bit[i] 存储的是原数组 a 中某些元素的和。

树状数组的构建

  1. 更新操作

    • 更新 a[i] 时,需要更新 bit 中所有包含 a[i] 的元素。
    • 具体操作是:从 i 开始,不断将 i 加上其最低位的 1,直到超出数组范围。
  2. 查询操作

    • 查询 a[0] + a[1] + ... + a[i] 时,需要累加 bit 中某些元素的值。
    • 具体操作是:从 i 开始,不断将 i 减去其最低位的 1,直到 i 变为 0。

lowbit 原理

lowbit 是一个在树状数组(Binary Indexed Tree, BIT)中常用的操作,用于获取一个整数的二进制表示中最低位的 1 及其后面的 0 所构成的数值。具体来说,lowbit(x) 返回的是 x 的二进制表示中最低位的 1 及其后面的 0 所构成的数值。

原理

lowbit 的原理基于补码表示法。对于一个正整数 x,其 lowbit 可以通过以下公式计算:

[ \text{lowbit}(x) = x & (-x) ]

这里的 & 表示按位与操作。

解释

  1. 补码表示

    • 在计算机中,负数通常以补码形式存储。对于一个正整数 x,其负数 -x 的补码表示是 x 的二进制表示按位取反后加 1。
  2. 按位与操作

    • 按位与操作 & 会将两个数的二进制表示中对应位都为 1 的位保留,其他位变为 0。
  3. 计算 lowbit

    • 对于一个正整数 x,其补码表示 -x 的二进制形式中,最低位的 1 及其后面的 0 会与 x 的二进制形式中相同位置的 1 对应。
    • 因此,x & (-x) 的结果就是 x 的二进制表示中最低位的 1 及其后面的 0 所构成的数值。

示例

假设 x = 6,其二进制表示为 0110

  1. x 的补码表示 -x-6,其二进制表示为 1010(按位取反后加 1)。
  2. 进行按位与操作:
    • 0110 (6)
    • 1010 (-6)
    • 0010 (2)

因此,lowbit(6) 的结果是 2

以下是一个简单的 lowbit 函数实现:

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

代码实现

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+100,mod=998244353;
typedef long long ll;
typedef pair<int,int> PII;
int T;
int n,m;
int a[N];
int c[N];
int lowbit(int x)
{return x&(-x);
}
int query(int x)
{int s=0;for(;x>0;x-=lowbit(x)){s+=c[x];}return s;
}
void modify(int id,int x)
{for(;id<=n;id+=lowbit(id)){c[id]+=x;}
}
void solve()
{cin>>n>>m;for(int i=1;i<=n;i++) cin>>a[i],modify(i,a[i]);while(m--){int id,x,y;cin>>id>>x>>y;if(id==1) modify(x,y);else cout<<query(y)-query(x-1)<<endl;}
}
signed main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);T=1;//cin>>T;while(T--){solve();}return 0;
} 

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

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

相关文章

python作业二

# 二进制转化为十进制 num input("num:")def binaryToDecimal(binaryString):he 0length len(binaryString)for i in range(length):he int(binaryString[i]) * 2 ** (length - i - 1)return heprint(binaryToDecimal(num))代码运行如下&#xff1a; import math…

特种设备管理为什么这么难?为何它是安全生产的重中之重?

随着工业化进程的加速和科技水平的不断提升&#xff0c;特种设备作为工业生产、公共服务和基础设施建设中的关键要素&#xff0c;其应用范围日益广泛&#xff0c;从大型压力容器、锅炉、电梯、叉车到压力管道、客运索道等&#xff0c;无一不渗透于我们日常生活的方方面面。然而…

【qt】QTcpSocket相关的信号

QTcpSocket可以在这里找到相关的信号 进行信号槽的关联 connect():这个信号在connectToHost()被调用并且连接已经成功建立之后发出 disconnected():该信号在套接字断开连接时发出 stateChanged(QAbstractSocket::SocketState socketState):每当QAbstractSocket的状态发生变化…

【若依前后端分离】通过输入用户编号自动带出部门名称(部门树)

一、部门树 使用 <treeselect v-model"form.deptId" :options"deptOptions" :show-count"true" placeholder"请选择归属部门"/> <el-col :span"12"><el-form-item label"归属部门" prop"dept…

音视频开发—使用FFmpeg从纯H264码流中提取图片 C语言实现

文章目录 1.H264码流文件解码流程关键流程详细解码流程详细步骤解析 2.JPEG编码流程详细编码流程详细步骤解析 3.完整示例代码4.效果展示 从纯H.264码流中提取图片的过程包括解码和JPEG编码两个主要步骤&#xff0c;以下是详细阐述 1.H264码流文件解码流程 关键流程 查找编解…

go语言处理特定格式的时间 例如打印出来2024-07-12 12:22:22 -2024-07-12 12:52:22

在Go语言中&#xff0c;你可以使用time包来创建、操作和格式化时间。要打印出两个特定时间&#xff08;例如开始时间和结束时间&#xff09;的字符串表示&#xff0c;并且格式化为YYYY-MM-DD HH:MM:SS这样的形式&#xff0c;你可以使用time.Format方法。 以下是一个例子&#x…

敏捷开发笔记(第10章节)--Liskov原则(LSP)

目录 1&#xff1a;PDF上传链接 10.1 Liskov替换原则&#xff08;LSP&#xff09; 10.2 一个违反LSP的简单例子 10.6 启发式规则和习惯用法 10.7 结论 1&#xff1a;PDF上传链接 【免费】敏捷软件开发(原则模式与实践)资源-CSDN文库 OCP背后的主要机制是抽象(abstraction…

group 与查询字段

需求 每周周一&#xff0c;统计菜单在过去一周&#xff0c;点击次数&#xff0c;和点击人数&#xff08;同一个人访问多次按一次计算&#xff09; 表及数据 日志表 CREATE TABLE t_data_log ( id varchar(50) NOT NULL COMMENT 主键id, operation_object varchar(500) DE…

【D3.js in Action 3 精译】1.3 D3 视角下的数据可视化最佳实践(下)

当前内容所在位置 第一部分 D3.js 基础知识 第一章 D3.js 简介 ✔️ 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知 1.2.1 HTML 与 DOM1.2.2 SVG - 可缩放矢量图形1.2.3 Canvas 与 WebGL1.2.4 CSS1.2.5 JavaScript1.2.6 Node 与 JavaScript 框架1.2.7 Observable 记事…

python工作中遇到的坑

1. 字典拷贝 有些场景下&#xff0c;需要对字典拷贝一个副本。这个副本用于保存原始数据&#xff0c;然后原来的字典去参与其他运算&#xff0c;或者作为参数传递给一些函数。 例如&#xff0c; >>> dict_a {"name": "John", "address&q…

我的世界1.21多种服务端开服教程,原版/Forge/Fabric/Paper/Mohist...,Minecraft开服教程

Minecraft&#xff08;MC&#xff09;1.21版多种服务端开服教程&#xff0c;我的世界1.21服务器搭建教程&#xff0c;MC原版/Forge/Fabric/Paper/Mohist服务端搭建教程&#xff0c;我的世界MOD/插件服开服教程。 本教程使用 Linux系统MCSManager 面板来搭建Minecraft服务器。 …

人工智能行业应用-垃圾识别一

垃圾识别应用主要体现在AI图像垃圾识别技术上&#xff0c;这是一种基于人工智能和计算机视觉技术的图像处理技术&#xff0c;广泛应用于各个领域以提高垃圾处理的效率和准确性。 1、垃圾识别效果图 2 垃圾识别任务分析 综合利用Python语言、Qt开发模块&#xff0c;OpenCV开发模…

数据结构(Java):单链表面试OJ题

1、题一&#xff1a;获取链表倒数第k个节点 . - 力扣&#xff08;LeetCode&#xff09; 1.1 思路解析 此题我们使用双指针法求解。 首先&#xff0c;我们要知道&#xff0c;倒数的第k个节点&#xff0c;距离倒数第一个节点还需要移动k-1次。 1.那么我们可以定义出两个指针&a…

MySQL之初识

SQL语句分类 1.数据定义语言DDL 简称DDL(Data Definition Language):用来定义数据库对象&#xff1a;数据库&#xff0c;表&#xff0c;列等。关键字&#xff1a;create&#xff0c;alter&#xff0c;drop等 2.数据操作语言DML 简称DML(Data Manipulation Language):用来对…

SQL去重的四种方法

去重是指&#xff1a;查询的时候, 不显示重复&#xff0c;并不是删除表中的重复项 数据表&#xff1a; 方法1&#xff1a;distinct去重 作用&#xff1a;只能一列去重&#xff0c;当distinct后跟大于1个参数时&#xff0c;他们之间的关系是&&(逻辑与)关系&#xff0c;…

lamda表达式使用

1、对象list中取某一个元素形成新的数组 bridgeInfos.stream().map(NavigableBridgePO::getId).collect(Collectors.toList()); 2、对象list中按某个元素分组形成新的map Map<String,List<ProjectFilePO>> projectFileMap projectFilePOS.stream().collect(Col…

00 Debian字符界面如何支持中文

作者&#xff1a;网络傅老师 特别提示&#xff1a;未经作者允许&#xff0c;不得转载任何内容。违者必究&#xff01; Debian字符界面如何支持中文 《傅老师Debian知识库系列之00》——原创 前言 傅老师Debian知识库特点&#xff1a; 1、拆解Debian实用技能&#xff1b; 2、…

ArcGIS获取21天免费教程,不用自己的邮箱

因为迟迟等不到3.1学习版本&#xff0c;但又很眼馋3.1的功能。 在群友的提醒下&#xff0c;官网免费注册21天试用&#xff0c;注册一次可以用21天&#xff0c;基本全部功能都可以使用。 &#xff08;也有群里的人用PayPal支付&#xff0c;然后设置离线许可&#xff0c;官网退…

Sentinel 学习笔记

Sentinel 学习笔记 作者&#xff1a;王珂 邮箱&#xff1a;49186456qq.com 文章目录 Sentinel 学习笔记[TOC] 前言一、基础概念二、Sentinel控制台2.1 安装控制台2.2 簇点链路2.3 请求限流2.4 线程隔离2.5 服务降级2.6 服务熔断 三、Sentinel客户端3.1 原始Jar包客户端3.2 Sp…

Python使用总结之jieba形容词提取详解

Python使用总结之jieba形容词提取详解 在自然语言处理&#xff08;NLP&#xff09;任务中&#xff0c;分词是一个基础且关键的步骤。对于中文文本处理&#xff0c;常用的分词工具之一是 jieba。 本文将详细介绍如何使用 jieba 库进行分词&#xff0c;并从文本中提取出形容词。 …