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

Cập nhật hình chữ nhật

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à phiên bản 2D của kỹ thuật mảng hiệu. Mỗi thao tác cập nhật hình chữ nhật (r1,c1,r2,c2,v) được mã hóa bằng bốn dấu chấm trên mảng hiệu d, sau đó lấy tổng tiền tố 2D một lần duy nhất là khôi phục được ma trận A.

Nhận xét quan trọng

  1. Nếu cộng trực tiếp lên mọi ô của hình chữ nhật thì chi phí mỗi thao tác là O(n·m), tổng chi phí lên tới O(q·n·m)≈2·1011 — không thể chấp nhận.
  2. Với mảng hiệu 1D, để cộng v trên đoạn [l,r] ta làm d[l]+=v và d[r+1]−=v. Mở rộng lên 2D, để cộng v trên hình chữ nhật [r1..r2]×[c1..c2] ta dùng nguyên lý bao hàm – loại trừ trên bốn góc.
  3. Toàn bộ giá trị có thể đạt cỡ q·vmax≈2·1014, phải dùng long long.

Thuật toán

Dựng mảng d[0..n+1][0..m+1] khởi tạo bằng 0. Với mỗi thao tác (r1,c1,r2,c2,v):

  • d[r1][c1]+=v
  • d[r1][c2+1]−=v
  • d[r2+1][c1]−=v
  • d[r2+1][c2+1]+=v

Sau đó dựng tổng tiền tố 2D ngay trên d (in-place): với 1≤i≤n, 1≤j≤m,

d[i][j]+=d[i−1][j]+d[i][j−1]−d[i−1][j−1].

Khi đó A[i][j]=d[i][j]. Trả lời mỗi truy vấn điểm (r,c) trong O(1).

Độ phức tạp

  • Thời gian: O(q+n·m+k).
  • Bộ nhớ: O(n·m) cho mảng hiệu / tổng tiền tố.

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