---
# System prepended metadata

title: BIT - Cây phân đoạn

---

# 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)**