树状数组

树状数组

树状数组的核心思想:分治。将数组以二叉树的形式进行维护区间之和。

a a a为原数组, t r e e tree tree为树状数组。 t r e e tree tree数组用于存储树上该结点下严格直连的子节点之和(例: t [ 1 ] = a [ 1 ] , t [ 2 ] = t [ 1 ] + a [ 2 ] , t [ 3 ] = a [ 3 ] , t [ 4 ] = t [ 2 ] + t [ 3 ] + a [ 4 ] t[1]=a[1],t[2]=t[1]+a[2],t[3]=a[3],t[4]=t[2]+t[3]+a[4] t[1]=a[1],t[2]=t[1]+a[2],t[3]=a[3],t[4]=t[2]+t[3]+a[4] t [ 5 ] = a [ 5 ] , t [ 6 ] = t [ 5 ] + a [ 6 ] , t [ 7 ] = a [ 7 ] , t [ 8 ] = t [ 4 ] + t [ 6 ] + t [ 7 ] + a [ 8 ] , t[5]=a[5],t[6]=t[5]+a[6],t[7]=a[7],t[8]=t[4]+t[6]+t[7]+a[8], t[5]=a[5],t[6]=t[5]+a[6],t[7]=a[7],t[8]=t[4]+t[6]+t[7]+a[8],…),即存储 [ x − l o w b i t ( x ) + 1 , x ] [x-lowbit(x)+1,x] [xlowbit(x)+1,x]区间之和

树状数组的操作:向下查询 向上修改

向下查询:查询前一个能代表其和的元素(例: s u m ( 4 ) = t [ 4 ] , s u m ( 3 ) = t [ 3 ] + t [ 2 ] , s u m ( 2 ) = t [ 2 ] , … sum(4)=t[4],sum(3)=t[3]+t[2],sum(2)=t[2],… sum(4)=t[4],sum(3)=t[3]+t[2],sum(2)=t[2],),可发现与下标的二进制表示有关,每次下标更新都在去掉二进制位中的最低的1,这一操作可用 i n d e x − = l o w b i t index-=lowbit index=lowbit实现。

向上修改:向后更新到其所有的代表结点(例:修改 a [ 3 ] a[3] a[3],需要修改 t [ 3 ] 、 t [ 4 ] 、 t [ 8 ] t[3]、t[4]、t[8] t[3]t[4]t[8]),可以发现每次更新是在下标二进制中最后一个1上+1,因此可通过 i n d e x + = l o w b i t index+=lowbit index+=lowbit实现。

注意:0没有 l o w b i t lowbit lowbit,因此树状数组下标必须从1开始。

树状数组

lowbit函数的实现

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

修改函数的实现(向上修改)

void update(int i,int num){//向上修改for(;i<=N;i+=lowbit(i))tree[i]+=num;
}

查询函数的实现(向下查询)

int query(int i){//向下查询int ans=0;for(;i>=1;i-=lowbit(i))//注意tree数组下标从1开始ans+=tree[i];return ans;
}

单点修改 区间查询(前缀和版树状数组)

  • 初始化
void init(){//初始化tree数组for(int i=1;i<=n;i++)//注意tree数组下标从1开始update(i,a[i]);//在初始化tree数组时num所传入参数为原数组值 
}
  • 单点修改(以将 x x x n u m num num为例)
extern int x,num;
update(x,num);
  • 区间查询(以查询 [ l , r ] [l,r] [l,r]为例)
extern int l,r;
query(r)-query(l-1);

区间修改 单点查询(差分版树状数组)

  • 初始化
void init(){for(int i=1;i<=n;i++)update(i,a[i]-a[i-1]);//num传入差分数组
}
  • 区间修改(以 [ l , r ] [l,r] [l,r]均加 n u m num num为例)
extern int l,r,num;
update(l,num),update(r+1,-num);
  • 单点查询(以查询 x x x为例)
extern int x;
query(x);

区间修改+区间查询(二阶树状数组)

(注:此类问题也可采用线段树求解。)

a 1 + a 2 + . . . + a n = d 1 + ( d 1 + d 2 ) + . . . + ( d 1 + . . . + d n ) = n × d 1 + ( n − 1 ) × d 2 + . . . + d n a_1+a_2+...+a_n=d_1+(d_1+d_2)+...+(d_1+...+d_n)=n\times d_1+(n-1)\times d_2+...+d_n a1+a2+...+an=d1+(d1+d2)+...+(d1+...+dn)=n×d1+(n1)×d2+...+dn

= n ∑ i = 1 n d i − ∑ i = 1 n ( i − 1 ) d i =n\sum\limits_{i=1}^{n} d_i-\sum\limits_{i=1}^{n}(i-1)d_i =ni=1ndii=1n(i1)di(核心公式)

因此,维护两个树状数组,一个用于实现 d i d_i di,另一个实现 ( i − 1 ) d i (i-1)d_i (i1)di

  • 查询函数、修改函数变更为:
void update1(int i,int num){for(;i<=n;i+=lowbit(i))t1[i]+=num;
}
void update2(int i,int num){for(;i<=n;i+=lowbit(i))t2[i]+=num;
}
int query1(int i){int ans=0;for(;i>=1;i-=lowbit(i))ans+=t1[i];return ans;
}
int query2(int i){int ans=0;for(;i>=1;i-=lowbit(i))ans+=t2[i];return ans;
}
  • 初始化函数(按照推导公式)
void init(){for(int i=1;i<=n;i++){update1(i,a[i]-a[i-1]);//对tree1传入差分数组update2(i,(i-1)*(a[i]-a[i-1]));//对tree2传入(i-1)*差分数组}
}
  • 区间修改(以 [ l , r ] [l,r] [l,r]均加 n u m num num为例)
extern int l,r,num;
update1(l,num),update1(r+1,-num);//对tree1加上差值
update2(l,(l-1)*num),update2(r+1,(r+1-1)*(-num));//对tree2加上差值(根据推导公式)
  • 区间查询(以查询 [ l , r ] [l,r] [l,r]为例)(本质:在求前缀和)
extern int l,r;
(r*query1(r)-query2(r))-((l-1)*query1(l-1)-query2(l-1));

应用

求区间之和

以上已给出。

求区间最值

求逆序数

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

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

相关文章

使用C++实现ATM系统,谈谈思路及代码实现

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

为什么需要重写equals和如何重写equals

首先先看Java中的 &#xff0c;比较的两个对象的地址值。 如果是基本数据类型&#xff0c;那么就是比较的是值。 如果是引用数据类型&#xff0c;比较的就是地址. object类中的equals方法也是用的&#xff1b; 所以要比较两个对象的大小&#xff0c;去调用默认的equals方法…

前端传到后端的data数组中有些属性值为空

将前端输入框中的值全部放入data中传入后端&#xff0c;但是在后端查看发现后端接收到的数据有些属性值为空。 第一种情况&#xff1a;只有第一个属性为空&#xff0c;其余属性接收正常 可能原因&#xff1a;后端用来接收的 比如前端发送数据&#xff1a; 实际上前端发送的数…

[图解]SysML和EA建模住宅安全系统-13-时间图

1 00:00:00,480 --> 00:00:02,280 首先&#xff0c;我们来看&#xff0c;图画在哪里 2 00:00:02,290 --> 00:00:04,380 这个图 3 00:00:04,390 --> 00:00:06,180 你看&#xff0c;它是描述&#xff0c;刚才讲的 4 00:00:06,190 --> 00:00:09,010 描述这个活动 …

两年经验前端带你重学前端框架必会的ajax+node.js+webpack+git等技术 Day2

前端框架必会的&#xff08;ajaxnode.jswebpackgit&#xff09;个人学习心得作业及bug记录 Day2 你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​ gitee https://gitee.com/Qiuner &#x1f339; 如果本…

昇思25天打卡营-mindspore-ML- Day14-VisionTransformer图像分类

今天学习了Vision Transformer图像分类&#xff0c;这是一种基于Transformer模型的图像分类方法&#xff0c;它不依赖卷积操作&#xff0c;而是通过自注意力机制捕捉图像块之间的空间关系&#xff0c;从而实现图像分类。 基本原理&#xff1a; 图像分块: 将原始图像划分为多个…

Java基础---复习01

main方法 一个程序有且只有一个main方法&#xff0c;main方法是java程序的唯一入口。 修饰符 修饰类修饰方法修饰域public都可以访问都可以访问private私有类只能本类只能本类protected子类可以继承、访问&#xff0c;同包下的类也可以访问子类可以继承、访问&#xff0c;同…

mmdetection中的Spatial-Transform-Decoupling项目部署,debug记录

1.安装环境 在这之前&#xff0c;因为是新的服务器&#xff0c;很多包没有安装 安装conda&#xff0c;在root/anaconda/bin 巴拉巴拉 vim~/bash.rc 按ESC 按&#xff1a;wq 删除是Delete sudo apt install libnccl22.7.8-1cuda11.0 libnccl-dev2.7.8-1cuda11.0bug1&#xff1…

基于单片机的空调控制器的设计

摘 要 &#xff1a; 以单片机为核心的空调控制器因其体积小 、 成本低 、 功能强 、 简便易行而得到广泛应用 。 本设计通过 &#xff21;&#xff34;&#xff18;&#xff19;&#xff33;&#xff15;&#xff12; 控制&#xff24;&#xff33;&#xff11;&#xff18;&a…

matlab:对带参数a关于x的方程求解

题目 讲解 简洁对各个式子的内部含义用浅显易懂的话语总结出来了&#xff0c;耐心体会 f(a) (x)exp(x)x^ax^(sqrt(x))-100;%因为下面的fzero的第一个数需要一个fun&#xff0c;所以这里有两个句柄&#xff0c;第一个a是输入的&#xff0c;第二个x是需要被解出的 A0:0.1:2;%创…

星光云VR全景系统源码

星光云VR全景系统源码 体验地址请查看

智能视频监控中心 - 详细介绍

目录 一、概述 &#xff08;一&#xff09;定义 &#xff08;二&#xff09;作用 1、系统安全性 2、整体管理效率 3、数据支持决策 4、促进企业集团化和智慧城市发展 二、原理和组成 &#xff08;一&#xff09;原理 &#xff08;二&#xff09;组网图 &#xff08;…

【从零到一,如何搭建本地AI大模型】

摘要: 本文主要记录这一段时间对本地大模型搭建的心得。 作为一个资深程序员,在AI席卷全球的时候,深深感觉到了一丝危机感,不禁有一个想法不断在脑海闪现:我会不会真的哪一天被AI给取代了? 从哪入手 程序员出生的我,掌握了很多语言,从前端到数据库,再到运维,基本都…

初识html——网页基础知识

Web相关术语 静态网页&#xff1a;只能浏览&#xff0c;不能实现客户端和服务器端的交流互动动态网页&#xff1a;网站页面随用户的输入而变化&#xff0c;能与客户端交流互动本地站点&#xff1a;一个在我们自己的计算机上&#xff0c;存储网站所有文件的临时文件夹远程站点&a…

【elasticsearch】IK分词器添加自定义词库,然后更新现有的索引

进入elasticsearch中的plugins位置&#xff0c;找到ik分词器插件&#xff0c;进入ik插件的config文件夹&#xff0c;当中有一个IKAnalyzer.cfg.xml配置文件。使用vim编辑器修改配置文件&#xff1a; vim IKAnalyzer.cfg.xml 配置文件如下&#xff08;添加了自定义字典的位置&…

领导有权利查看员工的电脑吗?违法吗?

在数字化办公环境中&#xff0c;企业领导是否可以查看员工的电脑成为了一个备受关注的话题。随着远程工作的普及和技术的发展&#xff0c;这个问题变得尤为复杂。 下面就由小编为大家分享关于企业领导查看员工电脑的权利范围&#xff0c;以及这种行为在何种情况下可能触犯法律…

美业SaaS系统有哪些?美业管理系统如何选?连锁美业门店收银系统源码

2024年业内较为知名、专业的美业门店管理系统软件有哪些&#xff1f;十大美业收银系统排名分享&#xff1a; 1.博弈美业 2.美务通 3.博卡 4.有赞美业 5.美管加 6.茂日软件 7.美问 8.伊智软件 9.剑琅管家 10.银豹美业 美业系统的选择取决于您的具体需求和业务规模。在选择美业系…

Windows下载安装配置并使用Redis(保姆级教程)

文章目录 1、Redis的下载与安装 2、Redis的使用 3、Redis的图形界面客户端 4、Redis开机自启动 1、Redis的下载与安装 下载Redis&#xff1a;https://pan.baidu.com/s/1zBonkO2y6AZeqCdRe0W5ow?pwd9999 提取码: 9999 下载后直接解压就可以使用了 2、Redis的使用 我们…

客户购买行为预测--Python数据分析

1、背景 客户购买行为预测是许多企业和组织所关注的一个重要问题&#xff0c;可以帮助它们更好地了解其客户的需求并制定更有效的销售和营销策略、优化产品营销等方面。 python可以通过使用各类库&#xff08;如numpy, pandas, matplotlib, scikit-learn等&#xff09;构建用于…

一文带你了解K8S组件架构

控制平面组件&#xff08;Control Plane Components&#xff09; 1. kube-apiserver 相当于一个通信部门&#xff08;秘书部&#xff09;&#xff0c;其他的部门都需要经过API进行信息的传递。 功能&#xff1a;作为Kubernetes的前端&#xff0c;提供REST API&#xff0c;处…