算法知识-树状数组的实现思路

树状数组倍增 ai​离散化后,第i个数出现过的次数。treei​树状数组。 阅读详情

1、树状数组的构建

![](https://i-blog.csdnimg.cn/direct/b89919d2f8f0432cb9c8b6541a3ab446.png)
public static void main(String[] args) {
    int[] a = {0,1,2,3,4,5,6,7,8}; // a[0] 不起作用,数组从 1 开始

    int[] c = new int[a.length]; // 由于 a 数组从 1 开始,因此直接就是 a 的长度即可 
    for(int i = 1;i < c.length;i++) {
        for(int j = i-lowbit(i)+1;j <= i;j++) {
            c[i] += a[j];
        }
    }
}

2、树状数组的前缀和查询

![](https://i-blog.csdnimg.cn/img_convert/e9a69aa8a2c3a2c3940b6621f4b6b6be.png)
// 前 n 项的和
static int sum(int n) {
    int res = 0; // 这里 i 一定要 > 0 ,因为,0 - lowbit(0) = 0 无限循环
    for(int i = n;i > 0;i -= lowbit(i)) {
        res += c[i];
    }
    return res;
}

3、树状数组的更新操作

![](https://i-blog.csdnimg.cn/img_convert/88f35a14633910ff44e1ddfbd223e1ff.png)
static void update(int k,int x) {
    for(int i = k;i < c.length;i += lowbit(i)) {
        c[i] += x;
    }
}

4、树状数组的区间更新、区间查询

package 算法第二章_数据结构.树状数组;

/**
 * ClassName:区间修改_区间查询
 * Description:
 *
 * @Author:独酌
 * @Create:2025/4/9 21:19
 */
public class 区间修改_区间查询 {
    // 构造树状数组,注意:这里由于 a 数组的第 0 项没有用,因此可以直接与 a 数组的长度一致
    public static void main(String[] args) {
        int[] a = {0, 1, 2, 3, 4, 5, 6, 7, 8};
        int[] d = new int[a.length]; // 差分数组
        int[] da = new int[a.length]; // 差分数组的辅助数组
        // 因此:要求 a 的前 4 项的和就等于
        // 【d 的从 1 ~ 4 的前缀和 * 4 】- 【da 的从 1 ~ 4 的前缀和】

        int[] c1 = new int[a.length]; // 差分数组树状数组
        int[] c2 = new int[a.length]; // 差分数组的辅助数组的树状数组,因为,区间查询需要
        for (int i = 1; i < d.length; i++) {
            d[i] -= d[i + 1 == d.length ? 0 : i + 1] -= a[i];
            da[i] = (i-1) * d[i];
        }

        // 初始化,差分数组的树状数组
        for(int i = 1;i < d.length;i++) {
            update(i,d[i],c1);
        }

        // 初始化,辅助数组的前缀和
        for(int i = 1;i < da.length;i++) {
            update(i,da[i],c2);
        }

        // 求 [2 ~ 4] 的和
        System.out.println(sum(4,c1,c2) - sum(1,c1,c2));

        updatePlus(2,4,3,c1,c2);

        // 求 [2 ~ 4] 的和
        System.out.println(sum(4,c1,c2) - sum(1,c1,c2));
    }


    static int lowBit(int x){
        return x & (-x);
    }
    static int sum(int n,int[] c){
        int res = 0;
        for(int i = n;i > 0;i -= lowBit(i)) {
            res += c[i];
        }
        return res;
    }
    static void update(int i,int x,int[] c){
        for(int j = i;j < c.length;j += lowBit(j)) {
            c[j] += x;
        }
    }

    static int sum(int n,int[] c1,int[] c2){
        return n * sum(n,c1) - sum(n,c2);
    }

    static void updatePlus(int l,int r,int x,int[] c1,int[] c2){
        update(l,x,c1);  // 修改差分数组
        update(r+1,-x,c1);

        update(l,x * (l-1),c2); // 修改辅助数组,因为d[i]变了(这里由于 da[i] = (i-1)d[i],因此,
                                   // 结果应该是:(i-1)*(d[i]+k),因此加上:(i-1) * k)
        update(r+1,-x * r,c2);
    }
}


逆序对问题的两种求解思路(归并排序和树状数组) 本文讲解了逆序对问题的两种标准求解方法 阅读详情

相关推荐

【树状数组】P9883 [EC Final 2021] Fenwick Tree|普及+

庞教授正在讲授关于 Fenwick 树(也称为二叉索引树)的课程。 在 Fenwick 树中,我们有一个长度为 $n$ 的数组 $c[1\ldots n]$,初始时全为零(对于任何 $1\le i\le n$,$c[i]=0$)。每次,庞教授可以对某个位置 $pos$($1\leq pos \leq n$)和一个值 $val$ 调用以下过程: ```cpp def update(pos, val): while (pos <= n): c[pos] += val

闻缺陷则喜何志丹 680

(CF792 ABCD题解) 模拟,树状数组

A题目链接:http://codeforces.com/problemset/problem/792/A// 题意: 给你n个数,问你两个数直接的差值得绝对值最小为多少,及有多少对满足这样的数/分析: 排序后直接扫一遍即可 // #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include

STILLxjy 870

modelsim软件安装教程及踩坑(极简版)

1.安装的网盘链接:链接:https://pan.baidu.com/s/1ltUfssyXlCnqDmLhWyhlwA提取码:jery 2.步骤(参考博文):https://blog.youkuaiyun.com/weixin_42693097/article/details/90523692?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163521788716780357213801%2522%252C%2522scm%2522%253A%2522

subtitle_的博客 3779

Codeforces数学1600----day1[同余定理,树状数组+两次二分,,组合计数]

1.C. Kuroni and Impossible Calculation **知识点:同余定理 ** #include <iostream> #include <cstdio> #include <stack> #include <sstream> #include <vector> #include <map> #include <cstring> #include <deque> #include &

weixin_45630722的博客 330

银河麒麟v10离线安装docker二进制包

因为工作需要在银河麒麟v10系统上离线部署k8s集群,k8s部署的前提是具有docker环境,因此离线安装docker成为必然。 1.下载docker包:Index of linux/static/stable/x86_64/ 选择自己合适的版本,我下载的是20.10.7 选择自己放置docker包的路径进行解压: cd /home/huawei/zq tar -zxvf docker-20.10.7.tgz 2. 给docker包解压出来的docker文件夹下的二进制文件赋..

q_hsolucky的博客 7683

紫光同创PGL50H开发板实战:盘古50KN网口板的高速通信与数据处理

本文详细介绍了紫光同创PGL50H开发板(盘古50KN网口板)在高速通信与数据处理领域的实战应用。文章从开箱、核心芯片解析、开发环境搭建入手,重点讲解了如何配置与测试其8路千兆以太网接口和SFP光纤接口,并深入探讨了FPGA与DDR3协同进行多路数据汇聚处理的系统架构与调试方法,为网络通信与高速数据处理系统开发提供了宝贵的实践经验。

weixin_28256233的博客 452

【ybtoj 高效进阶 4.2】【树状数组】 单点修改区间查询

【ybtoj 高效进阶 4.2】【树状数组】 单点修改区间查询 题目 解题思路 模板题 详细解释,戳戳这里 代码 #include<iostream> #include<cstdio> using namespace std; int n,m,x,y,w; long long c[1000010]; void add(int x,int y) //修改 { for (;x<=n;x+=x&(-x)) c[x]+=y; } long long

Y的博客 169

密评实战:应用层数据安全防护全解析

本文从实战角度深度解析三级信息系统密评中应用层数据安全防护的核心要点。围绕身份鉴别、访问控制、数据传输与存储安全、不可否认性等关键环节,结合国密算法(SM2/SM3/SM4)与智能密码钥匙等合规技术,提供了从代码审查、日志分析到流量验证的全链路排查方法,助力构建真正符合密评标准的数据安全防线。

weixin_29291185的博客 460

zzuli oj 多校训练(三)【树链剖分--树状数组---STL----二分图----二分----DP】

Problem F: D Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 178  Solved: 38 SubmitStatusWeb Board Description 晴天想把一个包含n个整数的序列a分成连续的若干段,且和最大的一段的值最小,但他有强迫症,分的段数不能超过m段,然后他就不会分了。。。他想问你这个分出来的和最

leibniz_zhang的博客 988

告别硬件!用Wokwi在线模拟ESP32点灯,5分钟搞定开发环境搭建

本文介绍如何使用Wokwi在线模拟器快速搭建ESP32开发环境,5分钟内完成点灯实验。无需硬件即可体验GPIO控制、PWM调光等核心功能,特别适合物联网开发初学者和快速原型验证。Wokwi的零成本、全功能模拟特性让嵌入式开发变得前所未有的简单高效。

weixin_42567497的博客 494

中职网络安全2021年国赛Wireshark流量分析题目解析

中职网络安全Wireshark流量分析题目解析

FRANXX_02的博客 6441

详解树状数组(C/C++)

树状数组(Binary Indexed Tree,简称BIT或Fenwick Tree)是一种用于高效处理数据序列的算法数据结构。它能够支持两个主要操作:单点更新和区间求和,这两个操作的时间复杂度都能达到O(log n),其中 n是数据序列的长度。树状数组非常适合处理那些需要频繁更新和查询区间和的问题。

闻道有先后,术业有专攻 2750

手把手教你学Simulink--控制策略与算法的DC-DC变换器领域仿真领域建模实例:基于Simulink实现一个双闭环控制Buck变换器的仿真建模

目录主要步骤1. 前期准备2. 构建Buck变换器模型3. 定义双闭环控制器4. 设置参考电压和反馈回路5. 实现双闭环控制器逻辑6. 仿真参数设置7. 运行仿真与结果分析示例整合代码片段1. Simulink模型2. 双闭环控制器参数调节3. 仿真结果分析总结双闭环控制是一种常见的控制策略,广泛应用于电力电子系统(如DC-DC变换器)中。它通过内外两个环路的协同工作,分别控制系统的动态性能和稳态性能。对于Buck变换器,通常采用电流内环和电压外环的双闭环控制结构。以下是一个手把手教程,帮助你基于Simul

MHD0815的博客 324

浅谈树状数组算法

树状数组很好用,可以将ONO(N)ON的时间复杂度优化到Olog⁡NO(\log N)OlogN。

OI 生涯中的一些笔记和题解。 876

YOLO11改进-注意力-引入Deformable Large Kernel Attention (DLKA) 解决多尺度、小目标、遮挡等问题

Deformable Large Kernel Attention (DLKA) 是一种用于视觉任务的注意力机制,旨在提升模型在处理不同尺寸和形状对象时的灵活性和性能。DLKA 的设计灵感源自传统的注意力机制,但通过引入可变形核(deformable kernel)来增强对局部特征的适应能力。

qq_64693987的博客 4042

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

树状数组 思路以及性能分析

特点 代码短、常数很小 应用及时间复杂度 区间查询:求前缀和 单点修改:给某个位置上的数加上一个数(同时能以非常小的代价维护前缀和) 时间复杂度:O(logn)O(logn)O(logn) 与一般前缀和算法的对比 算法 修改某个点 查询前缀和 平均时间复杂度(假定两种操作各占50%50\%50%) 一般前缀和 O(n)O(n)O(n) O(1)O(1)O(1) O(n)O(n)O(n) 树状数组 O(logn)O(logn)O(logn) O(logn)O(logn)O(logn

Alkali!的博客 614

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

算法篇:树状数组

介绍可以以较低时间复杂度来维护前缀和的二叉索引树

依稀_yixy的博客 1544

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

树状数组算法讲解及例题

的值,使其一直维护区间和。一直往上找,直到找到了一个点包含整个数组的区间和(根节点)为止。,那么和线段树的思想差不多,当子节点被改动时,上层节点的值也会变动,怎么找到上层节点呢?所覆盖的区间,查找下一个区间,所以就在统计完之后用。但是这道题是点查询,所以我们不用写真正的区间修改。的和,先看一下核心思想部分,那个部分讲过点。包含的,所以这个区间的元素和就存在点。每个位置的覆盖范围由二进制最低位的。树状数组的区间查询类似前缀和,是。的范围内,这个区间的点之和是被点。一次排在次低位的数。的值之后,就应该改动点。

STY_fish_2012的博客 801

【算法】树状数组数据结构

树状数组详解与算例分析

一些笔记 1316

[算法模板]树状数组

[算法模板]树状数组 思路 图片转自:yhf_2015——彻底理解树状数组 使用这个图片就能很快的理解树状数组。 我们可以先根据图片来分解一个十进制数成二次幂。 example: \(15=2^0+14\) \(14=2^1+12\) \(12=2^2+8\) \(8=2^3\) \(15=2^0+2^1+2^2+2^3\) 图上的每一个白条(包含灰块)就是\(c[i]\)覆盖的范围,而\(lo...

weixin_30429201的博客 316

TypeScript在Node.js后端开发中的实践指南

TypeScript作为JavaScript的超集,通过静态类型检查显著提升了代码质量和开发效率。在后端开发中,类型系统确保了API契约、数据模型和业务逻辑的严谨性,特别适合Node.js微服务架构。结合Express、NestJS等框架,开发者可以构建类型安全的RESTful API和数据库操作层。通过配置tsconfig.json和集成TypeORM等工具,TypeScript能够有效减少运行时错误并提升团队协作效率。本文以Node.js后端开发为场景,详解如何利用TypeScript的类型推断和现代E

weixin_33782386的博客 214

树状数组的简易讲解

树状数组是一种优化前缀和操作的数据结构,通过二进制分组降低单点修改的时间复杂度。核心原理是利用lowbit操作确定分组范围(x&-x),将数组元素按二进制位分成不同组别。初始化时从小到大累加元素值到包含它的各个组;查询前缀和时从大到小累加相关组的值;修改元素时更新所有包含该元素的组。相比传统前缀和数组,树状数组将单点修改的时间从O(n)优化到O(logn),但会略微增加初始化、查询等操作的时间。典型应用场景是需要频繁单点修改和区间查询的问题。

2401_88518969的博客 822

高级数据结构:树状数组以及逆序对求解

树状数组以及逆序对求解树状数组基础知识lowbit操作讲解单点更新区间查询树状数组应用之逆序对原理题目及代码推荐给大家的一段话 树状数组基础知识 树状数组是一个查询和修改复杂度都为log(n)的数据结构。主要用于数组的单点修改&&区间求和. 另外一个拥有类似功能的是线段树. 具体区别和联系如下: 两者在复杂度上同级, 但是树状数组的常数明显优于线段树, 其编程复杂度也远小于线段树. 树状数组的作用被线段树完全涵盖, 凡是可以使用树状数组解决的问题, 使用线段树一定可以解决, 但是线段树能够

艾 1762

并查集,ST表,树状数组总结

建最小生成树的过程中记录边的最大值即可。

m0_73553730的博客 2116

CSP-S算法模板详解:从设计思路到代码实现

在信息学竞赛中,优秀的模板代码能极大提升解题效率。但直接套用模板而不理解其原理,往往会导致在题目变种时束手无策。本文将深入解析5个核心算法模板的设计思路,帮助您真正掌握这些"竞赛利器"。传统数组的单点修改是O(1),但前缀和查询是O(n);前缀和数组的查询是O(1),但修改是O(n)。树状数组可以在**O(log n)**时间内完成这两种操作。建议在理解的基础上手写实现每个模板3-5次,直到能够独立完成所有细节。在容量限制下选择物品使总价值最大。单源最短路径问题(无负权边)高效计算大数幂(如求。

as_asdf的博客 851

数据结构与算法:树状数组

树状数组

2402_89326161的博客 908
上一篇: 算法知识-欧拉函数+快速幂+费马定理+组合数+容斥原理
下一篇: 面试专栏-02-MySQL知识点(第二部分)
o独酌o
博客等级 码龄3年 324粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值