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

Hình vuông lớn nhất tổng nhỏ

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

Bài toán yêu cầu tìm cạnh k lớn nhất sao cho tồn tại một hình vuông k×k có tổng ≤S. Hai kĩ thuật then chốt:

  1. Tổng tiền tố 2D (2D prefix sum) để tính tổng của một sub-rectangle bất kì trong O(1).
  2. Chặt nhị phân (binary search) trên đáp án k, dựa trên một tính chất đơn điệu.

Nhận xét quan trọng

  1. Đặt minSum(k)=min tổng trên mọi hình vuông k×k trong A. Vì mọi phần tử của A đều không âm, nên với bất kỳ hình vuông k×k nào, ta đều có thể "thu nhỏ" nó về một hình vuông (k−1)×(k−1) bằng cách bỏ bớt một hàng và một cột; tổng của hình vuông (k−1)×(k−1) không lớn hơn tổng của hình vuông k×k. Do đó minSum(k)≥minSum(k−1) — hàm minSum không giảm theo k.

  2. Suy ra: tập các k thoả mãn minSum(k)≤S là một tiền tố {0,1,…,k*}. Ta có thể chặt nhị phân để tìm k*.

  3. Tổng của một hình vuông k×k tối đa là 250000·109=2.5·1014, vượt phạm vi 32-bit. Phải dùng 64-bit (long long) khi xây mảng tiền tố và khi tính hiệu.

Thuật toán

Bước 1. Xây mảng tiền tố 2D: P[i][j]=∑a≤i,b≤jAa,b với công thức

P[i][j]=P[i−1][j]+P[i][j−1]−P[i−1][j−1]+Ai,j.

Bước 2. Định nghĩa hàm fits(k): tồn tại hình vuông k×k với tổng ≤S hay không. Với mỗi vị trí góc trên-trái (r,c) (với r+k−1≤n, c+k−1≤m), tổng hình vuông tính bằng

P[r+k−1][c+k−1]−P[r−1][c+k−1]−P[r+k−1][c−1]+P[r−1][c−1].

fits(k) trả về true khi và chỉ khi giá trị nhỏ nhất trong các tổng đó ≤S. Phép kiểm tra này chạy trong O((n−k+1)(m−k+1))≤O(nm).

Bước 3. Chặt nhị phân trên k∈[0,min(n,m)]: tìm k lớn nhất sao cho fits(k) = true.

Độ phức tạp

  • Thời gian: O(nmlogmin(n,m)). Với n=m=500, đây là khoảng 500·500·9≈2,25·106 phép tính — rất nhanh.
  • Bộ nhớ: O(nm) cho mả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