Tô Màu Theo Số

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: Tô Màu Theo Số

Hướng tiếp cận

Bài toán yêu cầu đếm số vùng liên thông của các ô cùng màu trong một hình chữ nhật con tùy ý. Có hai cách tiếp cận chính: dùng công thức Euler cho đồ thị phẳng (Euler's formula), hoặc dùng cây đoạn 2 chiều (2D segment tree).

Nhận xét quan trọng

  1. Với một hình chữ nhật con, ta cần đếm số thành phần liên thông (TPLT) của đồ thị mà các đỉnh là ô và cạnh nối các ô liền kề cùng màu.

  2. Cây đoạn 2D (2D Segment Tree): Phân rã hình chữ nhật thành các đoạn được lưu sẵn trong cây đoạn. Mỗi nút lưu số TPLT và danh sách ID thành phần ở các biên (trên, dưới, trái, phải). Khi truy vấn, ghép các đoạn và dùng union-find để hợp nhất TPLT tại các biên chung.

  3. Union-Find với timestamp: Để tránh reset union-find O(N+M) lần mỗi truy vấn, dùng mảng seen[] lưu timestamp. Khi truy cập phần tử lần đầu trong một truy vấn mới, tự động khởi tạo nó.

Thuật toán

Xây dựng cây đoạn 2D
  • Cây đoạn ngoài phân chia theo hàng (Y), cây đoạn trong phân chia theo cột (X).
  • Mỗi nút [ny][nx] bao phủ hình chữ nhật [sy1,sy2] x [sx1,sx2] lưu:
    • amt: số TPLT trong hình chữ nhật này
    • top[x], bot[x]: ID TPLT của ô ở hàng đầu/cuối, cột x
    • lft[y], rgt[y]: ID TPLT của ô ở hàng y, cột đầu/cuối
  • Khi ghép hai đoạn theo chiều dọc (hàng midymidy+1):
    • Với mỗi cột x: nếu canvas[midy][x] == canvas[midy+1][x], hợp nhất hai TPLT.
  • Khi ghép hai đoạn theo chiều ngang: tương tự với cột.
Trả lời truy vấn
  1. Khởi tạo timestamp mới, cur_res = 0.
  2. Dùng cây đoạn tìm các nút bao phủ [r1,r2] x [c1,c2].
  3. Với mỗi nút được chọn, thêm amt[ny][nx] vào cur_res và hợp nhất tại các biên chung.
  4. Kết quả sau khi hợp nhất là cur_res.

Độ phức tạp

  • Xây dựng: O(NMlogNlogM)
  • Mỗi truy vấn: O((N+M)logNlogM)
  • Tổng: O(NMlogNlogM+Q(N+M)logNlogM)

Với N=M=1000, Q=1000: vừa đủ trong giới hạn thời gian mở rộng.


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