一维二维树状数组模板(进阶版)

一维二维树状数组模板题加题解_eyuhaobanga的博客-CSDN博客后,发现树状数组写的太丑了,决定改变一下

一维:

树状数组 1 :单点修改,区间查询 - LibreOJ 130 - Virtual Judge

AC代码:

#include <bits/stdc++.h>
using namespace std;
// typedef long long i64;
using i64 = long long;

template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

template <typename T>
struct Fenwick {
    const int n;
    vector<T> a;
    Fenwick(int n) : n(n), a(n + 1) {}
    void add(int x, T v) {
        for (int i = x; i <= n; i += i & -i) {
            a[i] += v;
        }
    }
    T sum(int x) {
        T ans = 0;
        for (int i = x; i > 0; i -= i & -i) {
            ans += a[i];
        }
        return ans;
    }
    T rangeSum(int l, int r) {
        return sum(r) - sum(l - 1);
    }
};
int n, q;

void Solve() {
    cin >> n >> q;
    Fenwick<i64> fen(n);
    for (int i = 1; i <= n; i++) {
        i64 x;
        cin >> x;
        fen.add(i, x);
    }
    while (q--) {
        int op;
        cin >> op;
        if (op == 1) {
            int i;
            i64 x;
            cin >> i >> x;
            fen.add(i, x);
        }
        else {
            int l, r;
            cin >> l >> r;
            cout << fen.rangeSum(l, r) << '\n';
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int T = 1;
    // cin >> T;
    while (T--) {
        Solve();
    }

    return 0;
}

树状数组 2 :区间修改,单点查询 - LibreOJ 131 - Virtual Judge

AC代码:

#include <bits/stdc++.h>
using namespace std;
// typedef long long i64;
using i64 = long long;

template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

template <typename T>
struct Fenwick {
    const int n;
    vector<T> a;
    Fenwick(int n) : n(n), a(n + 1) {}
    void add(int x, T v) {
        for (int i = x; i <= n; i += i & -i) {
            a[i] += v;
        }
    }
    T sum(int x) {
        T ans = 0;
        for (int i = x; i > 0; i -= i & -i) {
            ans += a[i];
        }
        return ans;
    }
    T rangeSum(int l, int r) {
        return sum(r) - sum(l - 1);
    }
    void rangeAdd(int l, int r, T x) {
        add(l, x);
        add(r + 1, -x);
    }
};


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, q;
    cin >> n >> q;
    vector<i64> a(n + 1);
    vector<i64> c(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        c[i] = a[i] - a[i - 1];
    }
    Fenwick<i64> fen(n);
    for (int i = 1; i <= n; i++) {
        fen.add(i, c[i]);
    }
    while (q--) {
        int op;
        cin >> op;
        if (op == 1) {
            int l, r;
            i64 x;
            cin >> l >> r >> x;
            fen.rangeAdd(l, r, x);
        }
        else {
            int i;
            cin >> i;
            cout << fen.sum(i) << '\n';
        }
    }

    return 0;
}

树状数组 3 :区间修改,区间查询 - LibreOJ 132 - Virtual Judge

AC代码:

#include <bits/stdc++.h>
using namespace std;
// typedef long long i64;
using i64 = long long;

template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

template <typename T>
struct Fenwick {
    const int n;
    vector<T> a;
    Fenwick(int n) : n(n), a(n + 1) {}
    void add(int x, T v) {
        for (int i = x; i <= n; i += i & -i) {
            a[i] += v;
        }
    }
    T sum(int x) {
        T ans = 0;
        for (int i = x; i > 0; i -= i & -i) {
            ans += a[i];
        }
        return ans;
    }
    T rangeSum(int l, int r) {
        return sum(r) - sum(l - 1);
    }
    void rangeAdd(int l, int r, T x) {
        add(l, x);
        add(r + 1, -x);
    }
};


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, q;
    cin >> n >> q;
    vector<i64> a(n + 1);
    vector<i64> c(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        c[i] = a[i] - a[i - 1];
    }
    vector<Fenwick<i64>> fen(2, Fenwick<i64> (n));
    for (int i = 1; i <= n; i++) {
        fen[0].add(i, c[i]);
        fen[1].add(i, i * c[i]);
    }
    while (q--) {
        int op;
        cin >> op;
        if (op == 1) {
            int l, r;
            i64 x;
            cin >> l >> r >> x;
            fen[0].add(l, x);
            fen[0].add(r + 1, -x);
            fen[1].add(l, l * x);
            fen[1].add(r + 1, -x * (r + 1));
        }
        else {
            int l, r;
            cin >> l >> r;
            cout << (r + 1) * fen[0].sum(r) - fen[1].sum(r) - l * fen[0].sum(l - 1) + fen[1].sum(l - 1) << '\n';
        }
    }

    return 0;
}

二维:

二维树状数组 1:单点修改,区间查询 - LibreOJ 133 - Virtual Judge

AC代码:

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

template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

template <typename T>
struct Fenwick {
    const int n, m;
    vector<vector<T>> a;
    Fenwick(int n, int m) : n(n), m(m), a(n + 1, vector<T> (m + 1)) {}
    void add(int x, int y, T v) {
        for (int i = x; i <= n; i += i & -i) {
            for (int j = y; j <= m; j += j & -j) {
                a[i][j] += v;
            }
        }
    }
    T sum(int x, int y) {
        T ans = 0;
        for (int i = x; i > 0; i -= i & -i) {
            for (int j = y; j > 0; j -= j & -j) {
                ans += a[i][j];
            }
        }
        return ans;
    }
    T rangeSum(int a, int b, int c, int d) {
        return sum(a - 1, b - 1) + sum(c, d) - sum(c, b - 1) - sum(a - 1, d);
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, m;
    cin >> n >> m;
    int op;
    Fenwick<i64> fen(n, m);
    while (cin >> op) {
        if (op == 1) {
            int x, y;
            i64 k;
            cin >> x >> y >> k;
            fen.add(x, y, k);
        }
        else {
            int a, b, c, d;
            cin >> a >> b >> c >> d;
            cout << fen.rangeSum(a, b, c, d) << '\n';
        }
    }


    return 0;
}

二维树状数组 2:区间修改,单点查询 - LibreOJ 134 - Virtual Judge

AC代码:

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

template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

template <typename T>
struct Fenwick {
    const int n, m;
    vector<vector<T>> a;
    Fenwick(int n, int m) : n(n), m(m), a(n + 1, vector<T> (m + 1)) {}
    void add(int x, int y, T v) {
        for (int i = x; i <= n; i += i & -i) {
            for (int j = y; j <= m; j += j & -j) {
                a[i][j] += v;
            }
        }
    }
    T sum(int x, int y) {
        T ans = 0;
        for (int i = x; i > 0; i -= i & -i) {
            for (int j = y; j > 0; j -= j & -j) {
                ans += a[i][j];
            }
        }
        return ans;
    }
    T rangeSum(int a, int b, int c, int d) {
        return sum(a - 1, b - 1) + sum(c, d) - sum(c, b - 1) - sum(a - 1, d);
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, m;
    cin >> n >> m;
    int op;
    Fenwick<i64> fen(n, m);
    while (cin >> op) {
        if (op == 1) {
            int a, b, c, d;
            i64 k;
            cin >> a >> b >> c >> d >> k;
            fen.add(a, b, k);
            fen.add(a, d + 1, -k);
            fen.add(c + 1, b, -k);
            fen.add(c + 1, d + 1, k);
        }
        else {
            int x, y;
            cin >> x >> y;
            cout << fen.sum(x, y) << '\n';
        }
    }


    return 0;
}

二维树状数组 3:区间修改,区间查询 - LibreOJ 135 - Virtual Judge

这个就不放AC代码了,应该是输入有点小问题,所以总是wa,但是结果肯定是对的(应该可以保证)

代码:

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

template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

template <typename T>
struct Fenwick {
    const int n, m;
    vector<vector<T>> a;
    Fenwick(int n, int m) : n(n), m(m), a(n + 1, vector<T> (m + 1)) {}
    void add(int x, int y, T v) {
        for (int i = x; i <= n; i += i & -i) {
            for (int j = y; j <= m; j += j & -j) {
                a[i][j] += v;
            }
        }
    }
    T sum(int x, int y) {
        T ans = 0;
        for (int i = x; i > 0; i -= i & -i) {
            for (int j = y; j > 0; j -= j & -j) {
                ans += a[i][j];
            }
        }
        return ans;
    }
    T rangeSum(int a, int b, int c, int d) {
        return sum(a - 1, b - 1) + sum(c, d) - sum(c, b - 1) - sum(a - 1, d);
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, m;
    cin >> n >> m;
    vector<Fenwick<i64>> fen(4, Fenwick<i64> (n, m));
    int op;
    while (cin >> op) {
        if (op == 1) {
            int a, b, c, d;
            i64 x;
            cin >> a >> b >> c >> d >> x;
            fen[0].add(a, b, x), fen[0].add(a, d + 1, -x), fen[0].add(c + 1, b, -x), fen[0].add(c + 1, d + 1, x);
            fen[1].add(a, b, a * x), fen[1].add(a, d + 1, -a * x), fen[1].add(c + 1, b, -a * x), fen[1].add(c + 1, d + 1, a * x);
            fen[2].add(a, b, b * x), fen[2].add(a, d + 1, -b * x), fen[2].add(c + 1, b, -b * x), fen[2].add(c + 1, d + 1, b * x);
            fen[3].add(a, b, a * b * x), fen[3].add(a, d + 1, -a * b * x), fen[3].add(c + 1, b, -a * b * x), fen[3].add(c + 1, d + 1, a * b * x);
        }
        else if (op == 2) {
            int a, b, c, d;
            cin >> a >> b >> c >> d;
            i64 sum0 = a * b * fen[0].sum(a - 1, b - 1) + (c + 1) * (d + 1) * fen[0].sum(c, d) - (c + 1) * b * fen[0].sum(c, b - 1) - a * (d + 1) * fen[0].sum(a - 1, d);
            i64 sum1 = -fen[1].sum(a - 1, b - 1) * (b) - fen[1].sum(c, d) * (d + 1) + fen[1].sum(a - 1, d) * (d + 1) + fen[1].sum(c, b - 1) * b;
            i64 sum2 = -fen[2].sum(a - 1, b - 1) * (a) - fen[2].sum(c, d) * (c + 1) + fen[2].sum(a - 1, d) * (a) + fen[2].sum(c, b - 1) * (c + 1);
            i64 sum3 = fen[3].sum(a - 1, b - 1) + fen[3].sum(c, d) - fen[3].sum(a - 1, d) - fen[3].sum(c, b - 1);
            cout << sum0 + sum1 + sum2 + sum3 << '\n';
        }
    }


    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值