博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二叉索引树 树状数组
阅读量:5051 次
发布时间:2019-06-12

本文共 839 字,大约阅读时间需要 2 分钟。

树状数组 维护一个序列 a1 a2 a3……an

支持两种操作:

1. sum(int a,int b) a~b的区间和

2. add(int x,int d) 第x个数增加d

 

设lowbit(x)为x的二进制最右边的1表示的值

如lowbit(38288)=lowbit(1001010110010000)=10000=16

lowbit(i)=i&-i

 

在树状数组中,对于节点i,如果它是左子结点,父节点为i+lowbit(i);如果它是右子节点,那么父节点是i-lowbit(i)

(不要在意上面的手写)

设置一个数组C,C[i]=A[i-lowbit(i)+1]+A[i-lowbit(i)+2]+...+A[i]

C对应着那个黑块和它左面的白色长块,如C12=A9+A10+A11+A12

 

那么如何算前缀和S呢?

从i向上、左爬,把经过的C加起来,不一定沿树上的边,如S11=C11+C10+C8

如果修改了一个Ai,如何更新C?

从i开始向上、右爬,修改沿途的C即可。如修改了A3,C3->C4->C8

代码:(短小精悍)

int sum(int x){    int ans=0;    while(x>0){        ans+=C[x];        x-=lowbit(x);    }    return ans;}void add(int x,int d){    while(x<=n){        C[x]+=d;        x+=lowbit(x);    }}

时间复杂度为log(n)

预处理先把A、C清空,进行n次add,n log n

 

树状数组相比线段树的优势:空间复杂度略低,编程复杂度低,容易扩展到多维情况。

劣势:适用范围小,对可以进行的运算也有限制,比如每次要查询的是一个区间的最小值,似乎就没有很好的解决办法。

 

转载于:https://www.cnblogs.com/FuTaimeng/p/5554474.html

你可能感兴趣的文章
几款Http小服务器
查看>>
iOS 数组排序
查看>>
第三节
查看>>
PHP结合MYSQL记录结果分页呈现(比较实用)
查看>>
Mysql支持的数据类型
查看>>
openSuse beginner
查看>>
Codeforces 620E(线段树+dfs序+状态压缩)
查看>>
Windows7中双击py文件运行程序
查看>>
Market entry case
查看>>
bzoj1230 开关灯 线段树
查看>>
LinearLayout
查看>>
学习python:day1
查看>>
css3动画属性
查看>>
第九次团队作业-测试报告与用户使用手册
查看>>
Equal Sides Of An Array
查看>>
CentOS笔记-用户和用户组管理
查看>>
Mongodb 基本命令
查看>>
Qt中QTableView中加入Check列实现
查看>>
“富豪相亲大会”究竟迷失了什么?
查看>>
控制文件的备份与恢复
查看>>