树状数组总结

非常棒的总结

 

模板题

洛谷 P3374 【模板】树状数组 1

单点修改+区间查询

#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;
}

 

区间修改+单点查询

洛谷 P3368 【模板】树状数组 2

#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;
}

 

posted @ 2018-09-21 21:28  Sugewud  阅读(108)  评论(0编辑  收藏  举报