继一维二维树状数组模板题加题解_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; }
一维二维树状数组模板(进阶版)
于 2022-05-12 21:05:48 首次发布