# BIT 2 chiều, range update, range query :::info > **Người làm**: Trần Thiên Phúc - 12Ti - K28, THPT Chuyên Hùng Vương, Thành phố Hồ Chí Minh. > **Nội dung**: > [TOC] > Tài liệu tham khảo: [Robert1003 blog](https://robert1003.github.io/2020/01/27/fenwick-tree.html#d-range-update-range-query-1). > Bài tập áp dụng: [VNOI Wiki](https://wiki.vnoi.info/algo/data-structures/fenwick-2d#b%C3%A0i-t%E1%BA%ADp-%C3%A1p-d%E1%BB%A5ng), [LDQOJ](https://www.lqdoj.edu.vn/problem/dhbb2022table), [VNOJ](https://oj.vnoi.info/problem/hspc14k). > Bài viết trên VNOJ: [VNOJ](https://oj.vnoi.info/user/TranThienPhuc2657). ::: --- - Hai truy vấn: - Update hình chữ nhật góc trái trên là $(x_{1}, \ y_{1})$ tới ô phải dưới là $(x_{2}, \ y_{2})$ cộng $val$ - Tổng hình chữ nhật góc trái trên là $(x_{1}, \ y_{1})$ tới ô phải dưới là $(x_{2}, \ y_{2})$ ## Định nghĩa mảng hiệu: $$d_{i, \ j} = a_{i, \ j} - a_{i - 1, \ j} - a_{i, \ j - 1} + a_{i - 1, \ j - 1}$$ $$\rightarrow a_{i, \ j} = \sum_{k = 1}^{i} \sum_{l = 1}^{j} d_{k, \ l}$$ ## Update - $d_{x_{1}, \ y_{1}} \mathrel{+}= val$ - $d_{x_{2} + 1, \ y_{1}} \mathrel{-}= val$ - $d_{x_{1}, \ y_{2} + 1} \mathrel{-}= val$ - $d_{x_{2} + 1, \ y_{2} + 1} \mathrel{+}= val$ ## Query Định nghĩa $p_{i, \ j}$ là tổng tiền tố từ ô $(1, 1)$ tới ô $(i, j)$ $$p_{i, \ j} = \sum_{k = 1}^{i} \sum_{l = 1}^{j} a_{k, \ l}$$ Như vậy đán án cần trả về là: $p_{i, \ j} - p_{i - 1, \ j} - p_{i, \ j - 1} + p_{i - 1, \ j - 1}$ ### Tính $p_{i, \ j}$ $$p_{i, \ j} = \sum_{k = 1}^{i} \sum_{l = 1}^{j} a_{k, \ l}$$ $$= \sum_{k = 1}^{i} \sum_{l = 1}^{j} \sum_{p = 1}^{k} \sum_{q = 1}^{l} d_{p, \ q}$$ Ta nhận thấy: mỗi $d_{p, \ q}$ được cộng lên $1$ lần với $k \geq p$ và $l \geq q$ Cố định $d_{k, \ l}$ ta có số lần được cộng của nó với mỗi $(i, j)$ là $(i - k + 1) \times (j - l + 1)$ $$= \sum_{k = 1}^{i} \sum_{l = 1}^{j} (i - k + 1) \times (j - l + 1) \times d_{k, \ l}$$ Ta nhân phân phối các biến trong ngoặc: $$= \sum_{k = 1}^{i} \sum_{l = 1}^{j} [(i + 1) - k] \times [(j + 1) - l] \times d_{k, \ l}$$ $$= \sum_{k = 1}^{i} \sum_{l = 1}^{j} [(i + 1) \times (j + 1) \times d_{k, \ l}] - [(i + 1) \times l \times d_{k, \ l}] - [k \times (j + 1) \times d_{k, \ l}] + [k \times l \times d_{k, \ l}]$$ Ở đây ta có thể rời rạc hóa như sau: $$= \sum_{k = 1}^{i} \sum_{l = 1}^{j} (i + 1) \times (j + 1) \times d_{k, \ l} - \sum_{k = 1}^{i} \sum_{l = 1}^{j} (i + 1) \times l \times d_{k, \ l} - \sum_{k = 1}^{i} \sum_{l = 1}^{j} (j + 1) \times k \times d_{k, \ l} + \sum_{k = 1}^{i} \sum_{l = 1}^{j} k \times l \times d_{k, \ l}$$ Các hằng số $i + 1$ và $j + 1$ không cần bỏ vào trong tổng nên là có thể bỏ ra ngoài: $$= (i + 1) \times (j + 1) \times \sum_{k = 1}^{i} \sum_{l = 1}^{j} d_{k, \ l} - (i + 1) \times \sum_{k = 1}^{i} \sum_{l = 1}^{j} l \times d_{k, \ l} - (j + 1) \times \sum_{k = 1}^{i} \sum_{l = 1}^{j} k \times d_{k, \ l} + \sum_{k = 1}^{i} \sum_{l = 1}^{j} k \times l \times d_{k, \ l}$$ Bây giờ, ta có thể sử dụng $4$ BIT khác nhau với $4$ cách update khác nhau trên từng BIT và bài toán bây giờ là truy vấn tổng tiền tố bình thường. ## Độ phức tạp - Update: $\mathcal{O} (\log_{2} n \times \log_{2} m)$ - Query: $\mathcal{O} (\log_{2} n \times \log_{2} m)$ ## Code :::spoiler Code ``` cpp= struct Fenwick_tree { ll BIT[N][N][4]; void update(int x, int y, int val) { for (int idx = x; idx <= n; idx += idx & (-idx)) { for (int idy = y; idy <= m; idy += idy & (-idy)) { BIT[idx][idy][0] += val; BIT[idx][idy][1] += 1ll * y * val; BIT[idx][idy][2] += 1ll * x * val; BIT[idx][idy][3] += 1ll * x * y * val; } } } void update(int xl, int yl, int xr, int yr, int val) { update(xl, yl, val); update(xl, yr + 1, -val); update(xr + 1, yl, -val); update(xr + 1, yr + 1, val); } ll get(int x, int y) { ll res = 0; for (int idx = x; idx > 0; idx -= idx & (-idx)) { for (int idy = y; idy > 0; idy -= idy & (-idy)) { res += 1ll * (x + 1) * (y + 1) * BIT[idx][idy][0] - 1ll * (x + 1) * BIT[idx][idy][1] - 1ll * (y + 1) * BIT[idx][idy][2] + BIT[idx][idy][3]; } } return res; } ll get(int xl, int yl, int xr, int yr) { return get(xr, yr) - get(xl - 1, yr) - get(xr, yl - 1) + get(xl - 1, yl - 1); } }; ``` :::