树状数组学习笔记
树状数组学习笔记
简介
树状数组是一个可以在
原理
观察发现线段树中有很多的冗余的部分。
红色部分为冗余部分。
把冗余部分去掉。

把每个节点编个号。

把每个节点的子节点个数和父结点编号列表出来。
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|
1 | 2 | 1 | 4 | 1 | 2 | 1 | 8 |
2 | 4 | 4 | 8 | 6 | 8 | 8 | \ |
这个表有什么规律呢?
观察发现,编号为
每个点存储和就好了,比如点4存储
写法
修改
把点
查询
如果要查询
如何求前缀和呢?
节点
比如要求
具体实现看代码。
代码
int val[MAXN];
void change(int x,int data){//修改&建立
for(int i=x;i<=MAXN;i+=lowbit(i))val[i]+=data;
}
int ask(int x){//前缀和
int ans=0;
for(int i=x;i!=0;i-=lowbit(i))ans+=val[i];
return ans;
}
int ask(int l,int r){//查询
return ask(r)-ask(l-1);
}
二维树状数组
可以求出二维数组里的前缀和,时间复杂度
与一维树状数组相似。
int val[MAXN][MAXN];
void change(int x,int y,int data){//修改&建立
for(int i=x;i<=MAXN;i+=lowbit(i))
for(int j=y;j<=MAXN;j+=lowbit(j))
val[i][j]+=data;
}
int ask(int x,int y){//前缀和
int ans=0;
for(int i=x;i!=0;i-=lowbit(i))
for(int j=y;j!=0;j-=lowbit(j))
ans+=val[i][j];
return ans;
}
int ask(int x1,int y1,int x2,int y2){//查询
return ask(x2,y2)-ask(x2,y1-1)-ask(x1-1,y2)+ask(x1-1,y1-1);
}
本文来自博客园,作者:maniubi,转载请注明原文链接:https://www.cnblogs.com/maniubi/p/16948318.html,orz
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!