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

Tổng tiền tố trên cây

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

Với mỗi đỉnh u, gọi pref[u] là tổng trọng số trên đường đi từ gốc đến u. Khi đó:

pref[u]=pref[parent(u)]+wu

với pref[1]=w1. Sau khi tính sẵn pref[u] cho mọi đỉnh bằng một lần DFS, mỗi truy vấn chỉ cần in ra pref[u] trong O(1).

Nhận xét quan trọng

  1. Vì |wu|≤109 và cây có thể sâu tới 2·105 đỉnh, tổng có thể đạt đến 2·1014 — vượt phạm vi int. Phải dùng long long.
  2. Cây có thể là một đường thẳng dài (n = 2·10⁵). DFS đệ quy có thể gây tràn stack — nên dùng DFS lặp (stack thủ công) hoặc tăng sys.setrecursionlimit trong Python (nhưng đệ quy Python sâu 2·10⁵ vẫn rất chậm và có thể vẫn lỗi). Triển khai DFS lặp là an toàn nhất.

Thuật toán

  1. Đọc n, mảng trọng số w, các cạnh, dựng danh sách kề.
  2. Chạy DFS lặp từ đỉnh 1:
    • Dùng một stack chứa (u,parent).
    • Khi pop một đỉnh u, gán pref[u]=pref[parent]+wu (riêng gốc thì pref[1]=w1).
    • Đẩy các con của u (mọi hàng xóm khác parent) vào stack.
  3. Với mỗi truy vấn u, in ra pref[u].

Độ phức tạp

  • Thời gian: O(n+q).
  • Bộ nhớ: O(n).

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