You are on page 1of 6

Tìm kiếm nhị phân

Hàm số:
Bảng số:
Cách trâu mộng: 𝒏𝟔 :
for(i)
for(j)
for (u)
for (v)
xét hình (i, j, u, v). Nếu k = |u – i| = |v – j|:
for x = từ i -> u:
for(y = từ j -> v)
đếm xem có bao nhiêu số 1 trong hình
j v

u
Cách 2: Làm giảm độ phức tạp của thuật trên: Tính trước (prefix sum: Cần lưu KQ
Tính trước bảng cộng dồn:
1 0 1 1 1 2
1 1 2 2 3 6
1 -3 2 3 1 6
sum(3, 3)= sum(2, 3)+ sum(3, 2) – sum(2, 2) + a(3,3)

A SUM
0

i,j

u,v

for(i = 1-> m)
for(j = 1-> n)
sum(i, j) = sum(i – 1,j)+sum(i, j-1)-sum(i-1,j-1)+a(i,j)
Việc tính tổng 1 HCN (i, j) -> (u, v):
sum(i,j,u,v) = sum(u, v)-sum(u, j-1)-sum(i-1,v) +sum(i-1,j-1)
for(i)
for(j)
for (k = 1 -> min(m,n):
u = i + k, v = j + k;
sum = sum(i,j,u,v);
Nhận xét:
Nếu không tồn tại một hình vuông nào có độ dài = k toàn số 1 thì không thể tồn tại HV có kích thước > k
1 1 1 1

0 0

Cách 3: Chặt nhị phân độ dài k:


với mỗi độ dài này:
for(i)
for(j)
u = i + k - 1, v = j + k - 1
tính res =sum(i, j, u, v);
res == k * k

Bài TABLE 2
Nhận xét: nếu không tồn tại giá trị V mà tìm được hình vuông kích thước k x k có min == V thì không thể tồn tại hình vuông kxk nào có min > V.
vậy:
Chặt nhị phân giá trị V này:
Với mỗi giá trị V cần kiểm tra xem có tồn tại 1 hình vuông kxk mà mọi giá trị đều >= V hay không
Để tìm xem có tồn tại 1 hình vuông kích thước k x k mà mọi giá trị của nó đều > V ta làm như sau:
Với giá trị V:
Ta xây dựng 1 bảng B, kích thước m x n (cùng kích thước với A) theo nguyên tắc:
nếu a[i][j] >=V thì b[i][j] = 1, ngược lại b[i][j] = 0.
Sau khi xây dựng xong bảng B thì việc tìm 1 hình vuông k x k trên A mà mọi giá trị của nó đều >= V được đưa về bài toán: tìm 1 hình vuông kích thước k x k trên B sao cho mọi
giá trị đều = 1. (đây là phần check của bài TABLE)

Bài PAIR
Nhận xét 1: không thể sinh ra dãy C từ A và B theo thuật trên
Bài toán con cần giải quyết trước:
Cho trước 1 giá trị x, hỏi nếu theo cách của đề bài thì có bao nhiêu phần tử đứng trước x trong dãy C
A: 1 2 3 4
B: 1 2 3 4
Sắp xếp A và B tăng dần.
Cách 1:
for( mọi i = 1-> n)
Với mỗi a[i]: cần tìm xem có bao nhiêu giá trị b[j] mà a[i] + b[j] <= X
upper_bound: tìm giá trị đầu tiên trong b mà a[i] + b[j] > X: 1..j – 1
res+= j – 1;
Res chính là đáp án.
Cách 2: Dùng thuật toán hai con trỏ để đếm bằng cách i tiến dần trên A, j giảm dần trên B dựa trên nhận xét: nếu a[i] + b[j] > x thì mọi giá trị sau a[i] + b[j] đều > x-> không cần
đếm nữa.
Bài toán chính:
Nhận xét 2: Nếu tại giá trị x có nhiều hơn k phần tử đứng trước x -> đáp án phải nhỏ hơn x.
-> chặt nhị phân giá trị x.
Với mỗi giá trị x, ta đếm res theo bài toán chia nhỏ đã được xử lý ở trên

You might also like