canuc80k3108·9/50

Đếm Hậu Duệ Theo Độ Sâu

Nộp bài trên LQDOJ

Bài 3.2 · Euler Tour

Có một cây gốc gồm đỉnh, đánh số từ đến , với gốc là đỉnh . Với mỗi đỉnh từ đến , cha trực tiếp của nó là .

Độ sâu của một đỉnh là số cạnh trên đường từ gốc đến đỉnh đó; do đó gốc có độ sâu .

Mỗi truy vấn cho hai số u,d. Hãy đếm số đỉnh thỏa đồng thời:

  • thuộc cây con gốc , kể cả trường hợp ;
  • độ sâu tuyệt đối của bằng đúng .

Lưu ý là độ sâu tính từ gốc , không phải khoảng cách từ .

Input

  • Dòng đầu chứa số nguyên .
  • Dòng tiếp theo chứa số .
  • Dòng tiếp theo chứa số nguyên .
  • Mỗi dòng trong dòng cuối chứa hai số nguyên .

Output

  • In dòng; dòng thứ là số đỉnh thỏa truy vấn thứ .

Constraints

  • .
  • với mọi .
  • .
  • .
  • .

Scoring

  • Subtask ( số điểm): .
  • Subtask ( số điểm): Không có giới hạn bổ sung.

Example

Test 1

Input

9
1 1 2 2 3 3 6 6
6
1 2
2 2
3 3
6 2
6 1
8 3

Output

4
2
2
1
0
1

Giải thích: Ở độ sâu , cây con của gốc có các đỉnh , còn cây con của chỉ có . Đỉnh tự thuộc cây con của nó và có độ sâu , nhưng không thể có hậu duệ ở độ sâu .

Lời giải tóm tắt
  • Nhận xét: Trong preorder Euler, cây con u là đoạn thời gian vào [tin[u],tout[u]]. Nếu gom các đỉnh theo độ sâu, danh sách tin của từng độ sâu tự tăng dần theo thứ tự DFS. Một truy vấn vì thế là đếm số phần tử của danh sách độ sâu d nằm trong đoạn cây con.
  • Thuật toán: DFS lặp để tính tin,tout,depth; khi vào đỉnh v, thêm tin[v] vào atDepth[depth[v]]. Với truy vấn (u,d), dùng lower_bound(tin[u]) và upper_bound(tout[u]) trên atDepth[d]; hiệu hai vị trí là đáp án.
  • Chứng minh tính đúng đắn: Mỗi đỉnh có độ sâu d xuất hiện đúng một lần trong danh sách tương ứng. Theo tính chất đoạn cây con, đỉnh đó là hậu duệ của u đúng khi tin nằm trong [tin[u],tout[u]]; hai phép tìm cận đếm chính xác toàn bộ giao này và không đếm đỉnh ngoài cây con.
  • Độ phức tạp: Tiền xử lý O(n), mỗi truy vấn O(log n), bộ nhớ O(n).