trang chủ / bài tập / nearcows / lời giải

Bò Lân Cận

Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Tác giả: huunguyenhuunguyen

Lời giải: Bò Lân Cận

Hướng tiếp cận

Bài toán yêu cầu tính, với mỗi đỉnh x trên cây, tổng số bò trong khoảng cách K cạnh từ x.

Cách tiếp cận trực tiếp — với mỗi đỉnh x, BFS/DFS sâu K tầng — có độ phức tạp O(N·K) với hằng số lớn. Tuy nhiên, có một công thức DP thanh lịch hơn trên cây.

Nhận xét quan trọng

Định nghĩa A[x][r] = tổng số bò trong khoảng cách đúng bằng r từ đỉnh x.

  • A[x][0]=C[x] (chỉ bò tại đỉnh x).
  • Với r1: Xét tất cả các hàng xóm y của x. Mỗi hàng xóm y biết số bò trong khoảng cách r1 từ y, tức là A[y][r1]. Tổng này chứa mọi đỉnh trong khoảng cách r từ x nhưng đi qua y.

Vấn đề: khi cộng A[y][r1] cho mọi hàng xóm y, đỉnh x bản thân nó và các đỉnh trong khoảng cách r2 từ x bị đếm nhiều lần — mỗi hàng xóm đều "nhìn thấy" những đỉnh này.

Cụ thể, A[x][r2] bị đếm deg(x) lần (mỗi hàng xóm đóng góp 1 lần), nhưng ta chỉ muốn đếm 1 lần. Do đó ta trừ đi (deg(x)1)·A[x][r2].

Thuật toán

A[x][r]=yadj(x)A[y][r1](deg(x)1)·A[x][r2]

Công thức này chính xác trên cây vì không có chu trình — mỗi đường đi duy nhất, nên việc loại trừ kép được đơn giản hóa như trên.

Cài đặt:

  1. Đọc đồ thị, khởi tạo A[·][0]=C[·].
  2. Lặp r từ 1 đến K: với mỗi đỉnh x, tính A[x][r] theo công thức trên.
  3. In A[i][K] cho mỗi i.

Tối ưu bộ nhớ: Chỉ cần lưu 3 lớp r (lớp hiện tại, lớp r1, lớp r2) bằng mảng xoay (rolling array) kích thước 4, truy cập bằng chỉ số rmod4 (hoặc r&3).

Độ phức tạp

  • Thời gian: O(N·K) — vòng lặp K tầng, mỗi tầng duyệt O(N) đỉnh với tổng bậc O(N).
  • Bộ nhớ: O(N) — chỉ lưu 4 lớp DP, mỗi lớp N phần tử.

Với N=105K=20, thuật toán thực hiện khoảng 2×106 phép tính — rất nhanh.


Bình luận

Không có bình luận tại thời điểm này.

gnatmake 12.2.0 a68g 3.1.2 nasm 2.16.1 as_x64 2.46 awk 1.3.4 gcc 16.1.0 csc 6.12.0.200 g++ 16.1.0 g++-themis 16.1.0 g++17 16.1.0 g++20 16.1.0 g++23 16.1.0 clang++ 22.1.6 dmd 2.112.0 dart 3.12.1 gforth 0.7.3 gfortran 12.2.0 go 1.26.3 groovyc 5.0.6 javac 25.0.3 node 26.2.0 kotlinc 2.3.21 sbcl 2.2.9 lua 5.4.8 nim 2.2.10 fpc 3.2.2 fpc-themis 3.2.2 perl 5.36.0 php 8.5.6 pike 8.0 pypy3 7.3.23 python3 3.14.5 racket 8.7 ruby 4.0.5 rustc 1.96.0 csc 5.3.0 ctoj-scratch 0.0.1 sed 4.9 tclsh 8.6 bun 1.3.14 deno 2.8.1 v 0.5.1 zig 0.16.0