trang chủ / đề bài / psumtreelca / lời giải

Tổng đường đi trên cây (LCA)

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

Hướng tiếp cận

Đây là bài toán truy vấn tổng trọng số đỉnh trên đường đi giữa hai đỉnh trên cây. Ta dùng kỹ thuật tổng tiền tố trên cây kết hợp với LCA (Lowest Common Ancestor).

Nhận xét quan trọng

Gọi pref[u] là tổng trọng số của các đỉnh trên đường đi từ gốc 1 đến đỉnh u (gồm cả u). Với hai đỉnh u,v và l=LCA(u,v):

  • Đường u→v là hợp của đường l→u và đường l→v, giao tại đúng đỉnh l.
  • Tổng = pref[u]+pref[v]−2·pref[l]+wl.

Lý do: pref[u]−pref[l] là tổng các đỉnh từ con của l trên đường tới u cho đến u (không gồm l). Tương tự với v. Cộng lại rồi thêm wl chính là tổng cần tìm.

Thuật toán

  1. DFS (lặp, dùng stack) từ gốc 1 để tính depth[u], parent[u], pref[u]=pref[parent[u]]+wu.
  2. Binary lifting: dựng bảng up[k][u] = tổ tiên thứ 2k của u, với k=0,1,…,⌈log2n⌉. Truy hồi up[k][u]=up[k−1][up[k−1][u]].
  3. LCA(u,v): nâng đỉnh sâu hơn lên cho cùng độ sâu, sau đó nâng đồng thời từng bậc 2k giảm dần đến khi hai con trỏ chỉ vào hai đỉnh có cha chung.
  4. Trả lời truy vấn bằng công thức trên.

Độ phức tạp

  • Tiền xử lý: O(nlogn).
  • Mỗi truy vấn: O(logn).
  • Tổng: O((n+q)logn), phù hợp với n,q≤2·105.

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.47 awk 1.3.4 gcc 16.2.0 dotnet 10.0.402 g++ 16.2.0 g++-themis 16.2.0 g++17 16.2.0 g++20 16.2.0 g++23 16.2.0 clang++ 22.1.8 dmd 2.113.0 dart 3.13.6 gforth 0.7.3 gfortran 15.3.0 go 1.27.3 groovyc 5.1.3 javac 26.0.2.1 node 26.12.1 julia 1.13.2 kotlinc 2.4.21 lean 4.35.0 sbcl 2.2.9 lua 5.5.1 nim 2.2.12 fpc 3.2.2 fpc-themis 3.2.2 perl 5.42.3 php 8.5.12 pike 8.0 swipl 9.0.4 pypy3 7.3.23 python3 3.15.1 racket 8.7 ruby 4.0.8 rustc 1.99.1 csc 5.3.0 ctoj-scratch 0.0.1 sed 4.9 swiftc 6.4.1 tclsh 8.6 bun 1.4.4 deno 2.9.8 v 0.5.2 zig 0.17.0