@

基本定义

树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值;经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值(如果加入多个辅助数组则可以实现区间修改与区间查询)。

如何理解树状数组

树状数组,重点在于它是树状的 (这不废话吗)

大家都知道二叉树吧,贴一张二叉树的图给大家理解一下(自己画的有点丑)



我们把它变形一下...



现在定义每一列的顶端结点C[]数组



ps.最后一个图不是我画的

C[i]代表子树的叶子结点的权值之和, 这里以求和举例

如图可以知道

C[1]=A[1];

C[2]=A[1]+A[2];

C[3]=A[3];

C[4]=A[1]+A[2]+A[3]+A[4];

C[5]=A[5];

C[6]=A[5]+A[6];

C[7]=A[7];

C[8]=A[1]+A[2]+A[3]+A[4]+A[5]+A[6]+A[7]+A[8];

这就是树状数组的基本组成。

将C[]数组的结点序号转化为二进制

1=(001) C[1]=A[1];

2=(010) C[2]=A[1]+A[2];

3=(011) C[3]=A[3];

4=(100) C[4]=A[1]+A[2]+A[3]+A[4];

5=(101) C[5]=A[5];

6=(110) C[6]=A[5]+A[6];

7=(111) C[7]=A[7];

8=(1000) C[8]=A[1]+A[2]+A[3]+A[4]+A[5]+A[6]+A[7]+A[8];

对照式子可以发现 C[i]=A[i-2^ k+1]+A[i-2^k+2]+......A[i];

(k为i的二进制中从最低位到高位连续零的长度)例如i=8时,k=3;

可以自行带入验证;

现在引入lowbit(x)

lowbit(x) 其实就是取出x的最低位1 换言之 lowbit(x)=2^k k的含义与上面相同 理解一下

主要操作

添加元素

单点修改

单点查询

区间修改

区间查询

前两个普通数组能够O(1)时间复杂度完成,后两个普通数组需要O(n)时间复杂度完成,而树状数组最大只需要O(logn),这也正是树状数组的快捷之处。

代码实现

0.lowbit操作

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

不懂的看下上面引用的那一段

1.添加元素

void add(int s,int num)
{
for(long long i=s;i<=n;i+=lowbit(i))
tree[i]+=num;
return;
}

添加元素的操作可能有些不好理解,但同上,只要理解了lowbit操作,基本就能看懂这个添加操作了...

2.单点修改

这个操作普通数组只要O(1)的时间复杂度,但是树状数组需要最高 O(logn)的时间,因为在树状数组中数组中的一些元素是有联系的,修改其中一个就需要牵扯到很多...

void add(int x,int k)
{
while(x<=n)
{
tree[x]+=k;
x+=lowbit(x);
}
}

3.单点查询

依然,普通数组O(1),树状数组最高O(logn)

long long ask(long long s)
{
long long ans=0;
for(long long i=s;i>=1;i-=lowbit(i))
ans+=tree[i];
return ans;
}

4.区间修改

这个操作就是树状数组的强项之一了,普通数组O(n),树状数组也是不到O(logn)跑出来

void add(int s,int num)
{
for(long long i=s;i<=n;i+=lowbit(i))
tree[i]+=num;
}

p.s.把[x,y]区间的数加上s,需要add(x,s);add(y+1,-s);

5.区间查询

这依然是树状数组的强项,时间复杂度同4

int sum(int x)
{
int ans=0;
while(x!=0)
{
ans+=tree[x];
x-=lowbit(x);
}
return ans;
}

树状数组模板题:

只需要树状数组基本知识

需要用到差分

ov.

【基础算法-树状数组】入门-C++的更多相关文章

  1. 【bzoj3289】Mato的文件管理 离散化+莫队算法+树状数组

    原文地址:http://www.cnblogs.com/GXZlegend/p/6805224.html 题目描述 Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份 ...

  2. BZOJ3289 Mato的文件管理(莫队算法+树状数组)

    题目是区间逆序数查询. 莫队算法..左或右区间向左或右延伸时加或减这个区间小于或大于新数的数的个数,这个个数用树状数组来统计,我用线段树超时了.询问个数和数字个数都记为n,数字范围不确定所以离散化,这 ...

  3. poj2299树状数组入门,求逆序对

    今天入门了树状数组 习题链接 https://blog.csdn.net/liuqiyao_01/article/details/26963913 离散化数据:用一个数组来记录每个值在数列中的排名,不 ...

  4. HDU 6278 - Just h-index - [莫队算法+树状数组+二分][2018JSCPC江苏省赛C题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6278 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...

  5. 【BZOJ3289】Mato的文件管理 莫队算法+树状数组

    [BZOJ3289]Mato的文件管理 Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是 ...

  6. BZOJ 3289: Mato的文件管理[莫队算法 树状数组]

    3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 2399  Solved: 988[Submit][Status][Di ...

  7. 树状数组入门 hdu1541 Stars

    树状数组 树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构.主要用于查询任意两位之间的所有元素之和,但是每次 ...

  8. POJ 2299 Ultra-QuickSort 求逆序数 (归并或者数状数组)此题为树状数组入门题!!!

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 70674   Accepted: 26538 ...

  9. POJ 2352 stars (树状数组入门经典!!!)

    Stars Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 54352   Accepted: 23386 Descripti ...

随机推荐

  1. centos7.6编译安装php7.3

    刚开始搞环境装过集成,发现不好用,后来自己编译安装一些扩展啊设置的都很容易找到. 以前装过5.6.7.0发现不一样,最近出了7.3是php5速度的三倍,那有必要升级一下列. 由于之前安装过老版本,依赖 ...

  2. xv6解析-- 多处理器操作

    xv6可以运行多cpu的计算机上,这个os使用mycpu函数来标识初当前的cpu,使用struct cpu结构体来记录当前的CPU状态.使用cpus这些状态存放于cpus数组中,使用ncpu来标志cp ...

  3. 使用Duilib开发Windows软件(5)——使用VLC做视频播放

    需求:调用PC上的摄像头拍照. 实现思路:接入视频流,截屏获取照片. 早期的vlc安装包(Windows)是附带sdk包的,现在的安装后已经没有了,原因如下: VLC SDK下载连接:https:// ...

  4. const函数返回自身的引用也是常量引用

    const函数返回自身的引用也是const 解决:根据对象是否为consr重载

  5. 第四讲,数据目录表之导入表,以及IAT表

    一丶IAT(地址表) 首先我们思考一个问题,程序加载的时候会调用API,比如我们以前写的标准PE 那么他到底是怎么去调用的? 它会Call 下边的Jmp位置 而Jmp位置则是对一个全局变量取内容. 看 ...

  6. Sqlserver查询每组数据中最大的一条数据

    select * from ( SELECT ROW_NUMBER() over (PARTITION By name order by val) as rowId,tb_test.* FROM tb ...

  7. ASP.NET 使用 SyndicationFeed 输出 Rss

    以前生成 RSS 都是使用拼接 Xml 的方式生成的,不仅麻烦而且还不规范. #region 输出指定分类编号的消息源内容... /// <summary> /// 输出指定分类编号的消息 ...

  8. MVC的12种ActionResult介绍以及应用示例【转】

    一.介绍 1.ViewResult 表示一个视图结果,它根据视图模板产生应答内容.对应得Controller方法为View. 2.PartialViewResult 表示一个部分视图结果,与ViewR ...

  9. 客户端相关知识学习(十二)之iOS H5交互Webview实现localStorage数据存储

    前言 最近有一个需求是和在app中前端本地存储相关的,所以恶补了一下相关知识 webView开启支持H5 LocalStorage存储 有些时候我们发现写的本地存储没有起作用,那是因为默认WebVie ...

  10. extern c 解释

    extern "C"修饰的变量和函数是按照c的方式编译的 如果想用c++方式编译c代码,需要特殊标识 方法 #if defined(__cplusplus) || defined( ...