canuc80k6704·5/20

Đường Đi Đúng K Cạnh

Nộp bài trên LQDOJ

Bài 67 · Centroid Decomposition

Cho một cây vô hướng gồm đỉnh. Một đường đi được xác định bởi hai đầu mút phân biệt và là đường đi đơn duy nhất nối hai đỉnh đó.

Hãy đếm số đường đi có đúng cạnh. Hai hướng đi giữa cùng một cặp đầu mút chỉ biểu diễn một đường đi, vì vậy cặp và không được tính hai lần.

Input

  • Dòng đầu chứa hai số nguyên .
  • Mỗi trong dòng tiếp theo chứa hai số nguyên , cho biết có một cạnh vô hướng nối hai đỉnh và .

Output

  • In một số nguyên duy nhất: số đường đi đơn có đúng cạnh.
  • Kết quả có thể vượt giới hạn số nguyên -bit.

Constraints

  • .
  • .
  • cạnh trong input tạo thành một cây.

Scoring

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

Example

Test 1

Input

6 3
1 2
2 3
2 4
4 5
4 6

Output

4

Giải thích: Bốn đường đi dài đúng cạnh có hai đầu mút lần lượt là và . Không có cặp đầu mút nào khác cách nhau đúng cạnh.

Lời giải tóm tắt
  • Đếm các đường đi đi qua một centroid: Xét centroid c của thành phần hiện tại. Với một đỉnh u, gọi d(u) là khoảng cách từ c đến u.
  • Đếm các đường đi đi qua một centroid: Nếu hai đầu mút nằm ở hai nhánh khác nhau sau khi bỏ c, đường đi giữa chúng bắt buộc đi qua c và có độ dài d(u) + d(v). Ta duy trì freq[d]: số đỉnh ở độ sâu d thuộc c hoặc các nhánh đã xử lý.
  • Đếm các đường đi đi qua một centroid: Ban đầu freq[0] = 1, đại diện cho chính c. Với từng nhánh:
  • Đếm các đường đi đi qua một centroid: 1. Thu toàn bộ độ sâu không vượt quá k trong nhánh. 2. Với mỗi độ sâu d, cộng freq[k-d] vào đáp án. 3. Chỉ sau khi truy vấn xong cả nhánh mới chèn các độ sâu của nhánh vào freq.
  • Đếm các đường đi đi qua một centroid: Thứ tự hỏi trước, chèn sau bảo đảm không ghép hai đỉnh thuộc cùng một nhánh tại centroid này.
  • Phân rã: Sau khi xử lý mọi đường đi qua c, đánh dấu c đã tách và tiếp tục trên từng thành phần còn lại. Mảng freq được xóa ở đúng các chỉ số đã chạm để dùng lại hiệu quả.
  • Chứng minh đúng: Mọi cặp được cộng tại c có hai đầu ở hai nhánh khác nhau hoặc một đầu là c; do đó đường đi thật sự qua c. Điều kiện d(u)+d(v)=k bảo đảm đường có đúng k cạnh.
  • Chứng minh đúng: Trong một nhánh, các độ sâu chỉ được chèn sau khi nhánh đã truy vấn xong, nên không có cặp cùng nhánh bị tính tại c. Với hai nhánh khác nhau, nhánh được xử lý sau chỉ ghép với nhánh đã xử lý trước, nên mỗi cặp chỉ được cộng một lần.
  • Chứng minh đúng: Xét một đường đi hợp lệ bất kỳ. Ở centroid đầu tiên tách hai đầu mút sang hai thành phần khác nhau, đường đi được đếm. Trước thời điểm đó hai đầu còn cùng thành phần; sau thời điểm đó chúng không còn xuất hiện trong cùng một bài toán con. Vì vậy mỗi đường đi hợp lệ được đếm đúng một lần.
  • Độ phức tạp: Mỗi đỉnh xuất hiện ở O(log n) mức phân rã. Thời gian O(n log n), bộ nhớ O(n+k).