【模板】树状数组

【模板】树状数组

一维树状数组

#define lowbit(x) ((x) & (-x))

const int maxN = 1e6 + 10;

typedef long long ll;

struct BIT {
    ll data[maxN << 2];

    inline void add(int k, int x) {
        while (k <= N) {
            data[k] += x;
            k += lowbit(k);
        }
    }

    inline ll query(int k) {
        ll ans = 0;
        while (k >= 1) {
            ans += data[k];
            k -= lowbit(k);
        }
        return ans;
    }
};

单点修改区间查询

BIT B;

inline void add(int k, int x) {
	B.add(k, x);
}
inline ll query(int l, int r) {
	return B.query(r) - B.query(l - 1);
}

区间修改区间查询

BIT B1, B2;

inline void add(int l, int r, int x) {
	B1.add(l, x);
	B1.add(r + 1, -x);
	B2.add(l, x * (l - 1));
	B2.add(r + 1, -x * r);
}

inline ll query(int l, int r) {
	ll s1 = (l - 1) * B1.query(l - 1) - B2.query(l - 1);
	ll s2 = r * B1.query(r) - B2.query(r);
	    return s2 - s1;
}

二维树状数组

#define lowbit(x) ((x)&(-x))

const int maxN = 5e3;

typedef long long ll;

struct BIT2 {
	ll data[maxN][maxN];

	inline void add(int x, int y, int val) {
		for (int i = x; i <= N; i += lowbit(i)) {
			for (int j = y; j <= M; j += lowbit(j)) {
				data[i][j] += val;
			}
		}
	}

	inline ll query(int x, int y) {
		ll ans = 0;
		for (int i = x; i; i -= lowbit(i)) {
			for (int j = y; j; j -= lowbit(j)) {
				ans += data[i][j];
			}
		}
		return ans;
	}
};

单点修改矩阵查询

BIT2 B;

inline void add(int x, int y, int val) {
	B.add(x, y, val);
}

inline ll query(int x1, int y1, int x2, int y2) {
	return B.query(x2, y2) - B.query(x1 - 1, y2) - B.query(x2, y1 - 1) + B.query(x1 - 1, y1 - 1)
}

矩阵修改矩阵查询

BIT2 B1, B2, B3, B4;

inline void upd(int x, int y, ll k) {
	B1.add(x, y, k);
	B2.add(x, y, x * k);
	B3.add(x, y, y * k);
	B4.add(x, y, x * y * k);
}

inline ll que(int x, int y) {
	return 	B1.query(x, y) * (x + 1) * (y + 1) -
	        B2.query(x, y) * (y + 1) -
	        B3.query(x, y) * (x + 1) +
	        B4.query(x, y);
}

inline void add(int a, int b, int c, int d, ll x) {
	upd(a, b, x);
	upd(c + 1, d + 1, x);
	upd(c + 1, b, -x);
	upd(a, d + 1, -x);
}

inline ll query(int a, int b, int c, int d) {
	return que(c, d) - que(a - 1, d) - que(c, b - 1) + que(a - 1, b - 1);
}
posted @ 2022-08-22 16:22  Burnling  阅读(16)  评论(0编辑  收藏  举报