树状数组学习笔记

发布时间 2023-07-24 18:33:17作者: 123wwm

 

树状数组真的很精美,码量小,还很快,比线段树快多了[滑稽]。

一维树状数组

单点修改,区间查询

例题:

loj #130. 树状数组 1

lougu P9974【模板】树状数组 1

不多说,代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 5e5+5;
int n, m, c[N];

int lowbit(int k) {return k&-k;}

void add(int x, int d) {for (; x <= n; x += lowbit(x)) c[x] += d;}

int ask(int x) {
    int sum = 0;
    for (; x; x -= lowbit(x)) sum += c[x];
    return sum;
}

int main() {
    ios::sync_with_stdio(0);
    cin >> n >> m;
    for (int i = 1, x; i <= n; ++i) {
        cin >> x;
        add(i, x);
    }
    for (int op, x, y; m--; ) {
        cin >> op >> x >> y;
        if (op == 1) add(x, y);
        else cout << ask(y)-ask(x-1) << endl;
    }
    return 0;
}

 

区间修改,单点查询

例题:

loj #131. 树状数组 2
luogu P3368【模板】树状数组 2
不多说,代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 5e5+5;
int n, m, a[N], c[N];

int lowbit(int k) {return k&-k;}

void add(int x, int d) {for (; x <= n; x += lowbit(x)) c[x] += d;}

int ask(int x) {
    int sum = 0;
    for (; x; x -= lowbit(x)) sum += c[x];
    return sum;
}

int main() {
    ios::sync_with_stdio(0);
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    for (int op, x, y, k; m--; ) {
        cin >> op >> x;
        if (op == 1) {
            cin >> y >> k;
            add(x, k);
            add(y+1, -k);
        }
        else cout << a[x]+ask(x) << '\n';
    }
    return 0;
}