# BIT - Cây phân đoạn ### Kiến thức cần nắm: **[Bitwise Bù trừ 2](https://hackmd.io/@c3jv2tKJQeqHkvfbGE2CSA/B1uORSiKgx)** **Một số tính chất Bitwise cần nhớ**: - $-i \,\&\, i = (\sim i + 1) \,\&\, i = \text{lsb}(i)$ **vì**: - $\sim i \,\&\, i = 0$ - $\sim i + 1$ sẽ cộng vào bit thứ $0$ của $i$, khi đó: - Nếu tại đó là $0$ thì biến $0$ thành $1$. - Nếu tại đó là $1$ thì nó sẽ biến bit $0$ gần nhất thành $1$ (vì nếu tại $\sim i$ là $0$ thì tại $i$ nó là bit $1$). - Còn những bit $1$ liên tiếp đó khi cộng $1$ vào sẽ bị biến thành $0$ để khi AND thì ra $0$ (còn đoạn bit $1$ prefix thì vẫn giữ nguyên vị trí và **AND** cũng ra $0$). **Một vài định nghĩa:** $lsb(x)$ là $-x\&x$, là bit $1$ **phải nhất** của $x$ $($cũng là số có dạng $2^{k}$ **lớn nhất** sao cho $2^{k}$ $|$ $i$ , **c\m** bằng cách đặt nhân tử chung$).$ --- ### Nhận xét chính: - Mỗi $idx$ khi tăng lên sẽ sinh ra bit $1$ tại vị trí khác nhau. - Nhưng nó sẽ còn trùng **prefix** với $idx - 1$, còn bit mới sẽ được tính riêng (và nó sẽ chứa $-x \,\&\, x = 2^{\text{bit bé nhất của } idx}$ phần tử mới nhất vì những đoạn trước đã được chứa rồi). - Đoạn **prefix** sẽ được binary-lift qua (vì đã tính trước đó). - Khi đạt tới dạng $2^k$ thì nó reset lại từ đầu. $\Rightarrow$ Mỗi vị trí $idx$ sẽ quản lí những phần tử $a[i]$ nhất định, khi update chỉ cần tìm những đoạn đó để **update** là xong. --- ### Thao tác Get: **Ví dụ**: - $idx = \texttt{01110001011100[1000]}$ thì nó sẽ quản lí đoạn **suffix** dài $1000$ $($tức dài $2^{3}$, ghi $1000$ cho dễ hình dung$)$ và lấy thêm **kq** của đoạn: - $\texttt{01110001011100[0000]}$. Sau đó nó sẽ nhảy sang đoạn có độ dài - $\texttt{01110001011[1000000]}$. Tiếp đó, nó sẽ quản lí suffix dài $1000000$ và nó sẽ lấy thêm **kq** của đoạn dài : - $\texttt{0111000101[10000000]}$. Cứ lặp như vậy cho tới khi nào tới đoạn: - $\texttt{0[10000000000000000]}$ thì ta thấy rằng đoạn trên sẽ quản lí full đoạn của nó $($tức $[1 \dots 0\texttt{10000000000000000}]$, vì **idx** có dạng $2^{x}$ sẽ quản lí **full** đoạn$)$. Cộng lại những đoạn trên ta ra được tổng từ $[1 \dots idx]$. $\Rightarrow$ Độ phức tạp là **số bit bật** (rất dễ 😎). --- ### Thao tác Update Từ quan sát ở thao tác **get**, ta thấy được số **phần tử** của cây **BIT** là: - Đối với $1$ loại $lsb(x)$ thì số lượng số có $lsb$ đó là $2^{log(n) - lsb(x)}$ $^{position}$ - Có $log_{2}(n)$ loại $lsb$ **khác nhau**. $\Rightarrow$ **Vậy**: **Từ nhận xét trên ta có biểu thức**: -Gọi $\ell$ là $log_{2}(n)$: $E = 2^{\ell} \cdot 2^0 + 2^{\ell-1} \cdot 2^1 + 2^{\ell-2} \cdot 2^2 + \dots + 2^0 \cdot 2^{\ell}$ **Mỗi số hạng đều bằng**: $2^{\ell-k} \cdot 2^k = 2^{\ell}$ Có tổng cộng $\ell+1$ số hạng. **Do đó**: $E = (\ell+1) \cdot 2^{\ell}$ Vì $2^{\ell} = n$ và $\ell = \log_2 n$, ta được: $E = (\log_2 n + 1) \cdot n$ Vậy, **số phần tử** $($tức là **đpt** khi nó **update** $n$ phần tử$)$ của cây BIT là: $E \approx n \log(n)$ --- ### Vậy làm sao để tìm những bit mà chứa $a[i]$? **Quan sát**: - Đoạn mà $bit[j]$ sẽ quản lí là $[j - \text{lsb}(j) + 1, \, j]$. - Vậy thì một $bit[j]$ mà để chứa được $a[i]$ thì phải thỏa: $$ j - \text{lsb}(j) + 1 \leq i \leq j $$ $\Rightarrow i \in [j - \text{lsb}(j) + 1, \, j]$. --- ### Ví dụ: Xét $idx = \texttt{011100010111001000}$ - Điều hiển nhiên là **idx** bé nhất chứa $a[i]$ chính là $i$ rồi. - Dự đoán hình dạng của **idx** chứa $a[i]$: Có dạng: - $j \geq i$ - Bỏ $\text{lsb}(j)$ đi thì $j \leq i$ Quan sát lại $idx$ trong ví dụ trên thì: - Khi cho $1$ bit vào $idx$ đó thì chắc chắn $j > idx$. - Đằng trước nó phải không được phép có bit $1$ nào, vì: nếu có thì bit $1$ đó sẽ là $\text{lsb}$ của $j$, mà khi bỏ ra thì $j < idx$. - Do đó bit $1$ vừa thêm vào sẽ là $\text{lsb}(j)$. - Khi tạo $j$ mới thì nó **không được phép** đặt nhiều hơn $1$ bit vào vị trí bit $0$. --- ### Phân loại $j$: Có bao nhiêu loại $idx \, j$ mà $j > idx$? **1.** Có $> 1$ bit nằm ở vị trí cao hơn bit $1$ cao nhất của $idx$. **2.** Có đúng $1$ bit nằm cao hơn bit $1$ cao nhất của $idx$. **3.** Có cùng prefix với $idx$ và có $1$ bit đặt tại vị trí mà ở đó $idx$ là $0$, và suffix có một vài bit $1$. **4.** Giống loại $(3)$ nhưng không có suffix. **5.** Có duy nhất $1$ bit nằm cao hơn bit cao nhất của $idx$, còn prefix và suffix full $0$. **6.** Có trùng prefix với $idx$, có $1$ bit trùng với vị trí bit $1$ của $idx$ nhưng không có suffix. --- ### Kết luận: - TH **(1)**, **(2)**, **(3)** $\;\Rightarrow\;$ không hợp lệ $($vì $j - \text{lsb}(j) > i$$)$. - TH **(6)** $\;\Rightarrow\;$ bản thân nó đã $< i$. - Hợp lệ: TH **(4)**, **(5)**. $\Rightarrow$ Có thể hình dung được hình dạng của $idx \, j$ mà chứa được $a[i]$. --- ### Vòng for trong update: ```cpp for(; idx <= n; idx += -idx & idx) ``` **Độ phức tạp:** Với mỗi `a[i]` thì TH tệ nhất là mỗi lần nó cộng cho $2^{k}$ $+$ $2^{k+1}$ $+...+ 2^{log_{2}(n)}$ nên với $n$ phần tử thì tốn **nlogn** --- ### Các phiên bản khác **Phiên bản ko Latex (100% của mình edit, bản trong HackMD được format lại bởi GPT):** **[Click vào đây](https://surl.lu/heydql)** **Phiên bản GPT chỉnh sửa lại (GPT tự chấm 95/100):** **[Click vào đây](https://surl.li/ccgcqj)** **Đánh giá của GPT về blog này:** **[Click vào đây](https://surl.li/zwxcpw)**