树状数组总结
非常棒的总结
模板题
单点修改+区间查询
#include<cstdio>
#include<algorithm>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
const int MAXN = 5e5 + 10;
int f[MAXN], n, m;
inline int lowbit(int x) { return x & (-x); }
inline void add(int x, int q)
{
while(x <= n)
{
f[x] += q;
x += lowbit(x);
}
}
inline int sum(int x)
{
int res = 0;
while(x)
{
res += f[x];
x -= lowbit(x);
}
return res;
}
inline int ans(int a, int b) { return sum(b) - sum(a - 1); }
int main()
{
scanf("%d%d", &n, &m);
_for(i, 1, n)
{
int x; scanf("%d", &x);
add(i, x);
}
while(m--)
{
int k, x, y;
scanf("%d%d%d", &k, &x, &y);
if(k == 1) add(x, y);
else printf("%d\n", ans(x, y));
}
return 0;
}
区间修改+单点查询
#include<cstdio>
#include<algorithm>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
const int MAXN = 5e5 + 10;
int f[MAXN], n, m, last;
inline int lowbit(int x) { return x & (-x); }
inline void add(int x, int q)
{
while(x <= n)
{
f[x] += q;
x += lowbit(x);
}
}
inline int sum(int x)
{
int res = 0;
while(x)
{
res += f[x];
x -= lowbit(x);
}
return res;
}
int main()
{
scanf("%d%d", &n, &m);
_for(i, 1, n)
{
int x; scanf("%d", &x);
add(i, x - last);
last = x;
}
while(m--)
{
int k, x, y, q;
scanf("%d%d", &k, &x);
if(k == 1) scanf("%d%d", &y, &q), add(x, q), add(y + 1, -q);
else printf("%d\n", sum(x));
}
return 0;
}
二维树状数组
#include<cstdio>
#include<algorithm>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
const int MAXN = 1e4;
int f[MAXN][MAXN], n, m, p;
inline int lowbit(int x) { return x & (-x); }
inline void add(int x, int y, int q)
{
while(x <= n)
{
for(int i = y; i <= m; i += lowbit(i)) //注意for循环的写法
f[x][i] += q;
x += lowbit(x);
}
}
inline int sum(int x, int y)
{
int res = 0;
while(x)
{
for(int i = y; i; i -= lowbit(i))
res += f[x][i];
x -= lowbit(x);
}
return res;
}
inline int ans(int x1, int y1, int x2, int y2)
{
return sum(x1, y1) + sum(x2-1, y2-1) - sum(x1, y2 - 1) - sum(x2 - 1, y1);
}
int main()
{
scanf("%d%d%d", &n, &m, &p);
_for(i, 1, n)
_for(j, 1, m)
{
int x; scanf("%d", &x);
add(i, j, x);
}
while(p--)
{
int k, x, y, q, a, b;
scanf("%d%d%d", &k, &x, &y);
if(k == 1) scanf("%d", &q), add(x, y, q);
else
{
scanf("%d%d", &a, &b);
printf("%d\n", ans(a, b, x, y));
}
}
return 0;
}