学习笔记——二维树状数组
不知道为什么,就是想把这个坑给填了。。。
二维树状数组,本质上还是树状数组,只是在一维的基础上变成了二维。。。
单点修改 1到i,j查询和一维基本一样,直接上代码

#include<iostream> #include<cstdlib> #include<cstdio> #include<algorithm> #define N 3010 using namespace std; int a[N][N],n; inline int lowbit(int x){ return x&-x; } inline add(int x,int y,int del){ for(int i=x;i<=n;i+=lowbit(i)) for(int j=y;j<=n;j+=lowbit(j)) a[i][j]+=del; } inline sum(int x,int y){ int num=0; for(int i=x;i;i-=lowbit(i)) for(int j=y;j;j-=lowbit(j)) num+=a[i][j]; return num; } inline void Jimmy(){ } int main(){ Jimmy(); return 0; }
下面介绍一下区间修改和区间查询
定义bi,j表示i,j到n,n的修改量,实质是一个标记,在计算sigma时我们通过统计区间内标记个数得出区间修改量之和
我们设面积前缀和S
那么S(x,y)=sigma(i<=x and j<=y) ai,j +sigma(i<=x and j<=y) bi,j*(x-i+1)*(y-j+1)
=sigma(i<=x and j<=y) ai,j +sigma(i<=x and j<=y) bi,j*(x+1)*(y+1)-sigma(i<=x and j<=y) bi,j*i*(y+1)-sigma(i<=x and j<=y) bi,j*j*(x+1)+sigma(i<=x and j<=y) bi,j*i*j
所以我们维护四个数组 bi,j bi,j*i bi,j*j bi,j*i*j 就可以在logn时间内来完成查询了
区间修改呢,就是在矩形的四个角分别打上标记
x1,y1 +del
x2+1,y1 -del
x1,y2+1 -del
x2+1,y2+1 +del
每个标记修改4个数组,一共16次
然后就ok啦
(这里原来是一份错误的代码。。。果然还是理解错了,关于树状数组见新的一份整合版吧) 2017.4.09
学习来源:http://tonyfang.is-programmer.com/posts/206991.html
orzTonyFang
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步