1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
| #include <iostream>
inline size_t LowBit(const size_t &x) { return x & -x; }
template <class DataT> class BinaryIndexedTree2D final { DataT **data_; size_t size_y_, size_x_;
public: BinaryIndexedTree2D(const size_t &size_y, const size_t &size_x) : data_(new DataT *[size_y + 1]), size_y_(size_y), size_x_(size_x) { for (size_t y = 0; y <= size_y_; ++y) { data_[y] = new DataT[size_x_ + 1]; for (size_t x = 0; x <= size_x_; ++x) data_[y][x] = 0; } }
template <class Arr2DT> BinaryIndexedTree2D(const Arr2DT &arr2d, const size_t &size_y, const size_t &size_x) : BinaryIndexedTree2D(size_y, size_x) { for (size_t y = 1; y <= size_y_; ++y) for (size_t x = 1; x <= size_x_; ++x) { data_[y][x] += arr2d[y][x]; size_t &&xx = x + LowBit(x); size_t &&yy = y + LowBit(y);
if (xx <= size_x_) data_[y][xx] += data_[y][x]; if (yy <= size_y_) data_[yy][x] += data_[y][x]; if (xx <= size_x_ && yy <= size_y_) data_[yy][xx] += data_[y][x]; } }
~BinaryIndexedTree2D() { for (size_t y = 0; y <= size_y_; ++y) delete[] data_[y]; delete[] data_; }
void Add(const size_t &y, const size_t &x, const DataT &val) { for (size_t yy = y; yy <= size_y_; yy += LowBit(yy)) for (size_t xx = x; xx <= size_x_; xx += LowBit(xx)) data_[yy][xx] += val; }
DataT GetSum(const size_t &y, const size_t &x) const { DataT res = 0; for (size_t yy = y; yy; yy -= LowBit(yy)) for (size_t xx = x; xx; xx -= LowBit(xx)) res += data_[yy][xx]; return res; }
DataT GetSum(const size_t &y0, const size_t &x0, const size_t &y1, const size_t &x1) const { return GetSum(y1, x1) - GetSum(y0 - 1, x1) - GetSum(y1, x0 - 1) + GetSum(y0 - 1, x0 - 1); } };
template <class DataT> inline void Modify2D(BinaryIndexedTree2D<DataT> diff[], const size_t &y0, const size_t &x0, const size_t &y1, const size_t &x1, const DataT &val) { diff[0].Add(y0, x0, val); diff[0].Add(y1 + 1, x0, -val); diff[0].Add(y0, x1 + 1, -val); diff[0].Add(y1 + 1, x1 + 1, val);
diff[1].Add(y0, x0, val * x0); diff[1].Add(y1 + 1, x0, -val * x0); diff[1].Add(y0, x1 + 1, -val * (x1 + 1)); diff[1].Add(y1 + 1, x1 + 1, val * (x1 + 1));
diff[2].Add(y0, x0, val * y0); diff[2].Add(y1 + 1, x0, -val * (y1 + 1)); diff[2].Add(y0, x1 + 1, -val * y0); diff[2].Add(y1 + 1, x1 + 1, val * (y1 + 1));
diff[3].Add(y0, x0, val * y0 * x0); diff[3].Add(y1 + 1, x0, -val * (y1 + 1) * x0); diff[3].Add(y0, x1 + 1, -val * y0 * (x1 + 1)); diff[3].Add(y1 + 1, x1 + 1, val * (y1 + 1) * (x1 + 1)); }
template <class DataT> inline DataT Query(const BinaryIndexedTree2D<DataT> diff_tree[], const size_t &y, const size_t &x) { return (y + 1) * (x + 1) * diff_tree[0].GetSum(y, x) - (y + 1) * diff_tree[1].GetSum(y, x) - (x + 1) * diff_tree[2].GetSum(y, x) + diff_tree[3].GetSum(y, x); }
template <class DataT> inline DataT Query(const BinaryIndexedTree2D<DataT> diff_tree[], const size_t &y0, const size_t &x0, const size_t &y1, const size_t &x1) { return Query(diff_tree, y1, x1) - Query(diff_tree, y0 - 1, x1) - Query(diff_tree, y1, x0 - 1) + Query(diff_tree, y0 - 1, x0 - 1); }
int n, m;
int main() { std::ios::sync_with_stdio(0); std::cin.tie(0), std::cout.tie(0);
std::cin >> n >> m;
BinaryIndexedTree2D<int64_t> diff[4] = { BinaryIndexedTree2D<int64_t>(n, m), BinaryIndexedTree2D<int64_t>(n, m), BinaryIndexedTree2D<int64_t>(n, m), BinaryIndexedTree2D<int64_t>(n, m)};
for (int t, x, y, u, v, w; std::cin >> t >> x >> y >> u >> v;) { if (t == 1) { std::cin >> w; Modify2D<int64_t>(diff, x, y, u, v, w); } else { std::cout << Query(diff, x, y, u, v) << "\n"; } }
return 0; }
|