# Lời giải bài Network
### Tác giả: Võ Khắc Triệu, I2023
## 1. Tóm tắt đề
Cho cây $G$ có trọng số gồm $n$ $(1 \le n \le 10^5)$ đỉnh, các cạnh được đánh số từ $1$ đến $n - 1$, trả lời $m$ $(1 \le m \le 10^5)$ truy vấn thuộc $2$ dạng sau:
- $P\ a\ b\ c$: Trên đường đi từ $a$ đến $b$ có bao nhiêu cạnh có trọng số $\le c$.
- $T\ i\ c$: Nếu xóa cạnh thứ $i$ thì miền liên thông chứa đỉnh $v_i$ có bao nhiêu cạnh có trọng số $\le c$.
## 2. Thuật toán ngây thơ
- Đề nói gì làm nấy, xử lý các truy vấn trong thời gian tuyến tính $O(n)$
- Độ phức tạp: $O(m \times n)$
## 3. Cải tiến
### a. Tiền xử lý
- Nhận thấy rằng, ta cần biểu diễn cây dưới dạng cấu trúc dữ liệu khác (**HLD**, **Euler Tour**, ...) để có thể dễ dàng xử lý các truy vấn hơn. Trong lời giải này sẽ chỉ giải thích thuật dùng **Euler Tour**.
**[Tìm hiểu về HLD](https://vnoi.info/wiki/algo/data-structures/heavy-light-decomposition.md)**
**[Tìm hiểu về Euler Tour](https://usaco.guide/CPH.pdf#page=174)**
- **Nhận xét**: Giả sử ta có đáp án của truy vấn $P\ a\ b\ c$ và ta muốn trả lời đáp án cho truy vấn $P\ a\ b\ (c + 1)$, ta chỉ cần xét thêm các cạnh có trọng số $c + 1$ (tương tự với truy vấn loại $T$).
$\rightarrow$ Xử lý **offline**
- Ta sẽ sắp xếp lại các cạnh và các truy vấn theo thứ tự tăng dần về trọng số. Ta sẽ dựng một cây mới $G'$ và cập nhật trọng số theo giá trị đang xét.
- Giả sử xét tới giá trị $c$, nếu trong cây $G$ cạnh có trọng số $\le c$ thì trong cây $G'$ cạnh sẽ có trọng số là $1$, ngược lại là $0$.
- **Tính chất quan trọng của Euler Tour**: Xét một đỉnh $u$ trên cây. Giả sử cây con gốc $u$ có $r$ đỉnh và có vị trí trên **Euler Tour** là $p$.
$\rightarrow$ Các nút từ vị trí $p$ đến $p + r - 1$ trên **Euler Tour** sẽ thuộc cây con gốc $u$.
### b. Định nghĩa chung
- $sz_i$ là số đỉnh của cây con gốc $i$ trên cây $G$.
- $e_i$ là số hiệu đỉnh trên vị trí thứ $i$ của **Euler Tour**.
- $pos_i$ là vị trí của đỉnh thứ $i$ trên **Euler Tour**
### c. Truy vấn loại P
#### Định nghĩa
- Gọi $p_i$ là tổng trọng số từ gốc tới $i$.
#### Cập nhật
- Giả sử cập nhật trọng số của cạnh $u - v$ ($u$ gần gốc hơn $v$) từ $0$ thành $1$ trên đồ thị $G'$, thì với mọi đỉnh $i$ nằm trong cây con gốc $v$, $p_i$ tăng lên $1$.
$\rightarrow p_{e_i} = p_{e_i} + 1\ \forall\ pos_v \le i \le pos_v + sz_v - 1$
$\rightarrow$ Dùng cấu trúc dữ liệu cập nhật đoạn (**Fenwick Tree**, **Segment Tree**).
#### Trả lời
- Dễ thấy, đáp án cho truy vấn $a\ b$ là $p_a + p_b - 2 \times p_{lca(a, b)}$, với $lca(a, b)$ là tổ tiên chung thấp nhất của $a$ và $b$.
**[Tìm hiểu về LCA](https://vnoi.info/wiki/algo/data-structures/lca-binlift.md)**
Cả thao tác cập nhật và trả lời đều tốn $O(log(n))$.
### d. Truy vấn loại T
#### Định nghĩa
- Gọi $t_i$ là tổng trọng số của các cạnh từ $u$ đến các con trực tiếp của $u$ trên đồ thị $G'$
- Gọi $s_i$ là tổng của $t_j$ với mọi $j$ thuộc cây con gốc $i$
$\rightarrow s_i = \sum_{j = pos_i}^{pos_i + sz_i - 1} t_{e_j}$
#### Cập nhật
- Giả sử cập nhật trọng số của cạnh $u - v$ ($u$ gần gốc hơn $v$) từ $0$ thành $1$ trên đồ thị $G'$, thì $t_u$ tăng lên $1$
#### Trả lời
Ta sẽ bài toán thành $2$ trường hợp:
##### Trường hợp 1: $u_i$ là cha của $v_i$
- Dễ thấy, trong trường hợp này, khi cắt cạnh $u_i - v_i$ thì miền liên thông chứa $v_i$ sẽ chính là cây con gốc $v_i$
$\rightarrow$ Đáp án sẽ là $s_{v_i}$
##### Trường hợp 2: $v_i$ là cha của $u_i$
- Tương tự, trong trường hợp này, khi cắt cạnh $u_i - v_i$ thì miền liên thông chứa $u_i$ sẽ chính là cây con gốc $u_i$
$\rightarrow$ Các cạnh **chưa bị xóa** không thuộc cây con gốc $u_i$ sẽ thuộc miền liên thông chứa $v_i$.
- Ngoài ra, vì $v_i$ là cha của $u_i$
$\rightarrow$ Các cạnh không thuộc cây con gốc $v_i$ sẽ thuộc miền liên thông chứa $v_i$.
$\rightarrow$ Đáp án sẽ là $s_{root} - s_{v_i}$ với root là gốc của cây.
Ta có thể dễ dàng tính được $s_i$ bằng dùng các cấu trúc dữ liệu truy vấn đoạn (**Fenwick Tree**, **Segment Tree**).
Cả thao tác cập nhật và trả lời đều tốn $O(log(n))$.
### Độ phức tạp: $O(m \times log(n))$
### Code mẫu: [Link](https://ideone.com/cYvDjO)
### Tag: Tree Algorithm, Data Structure