You are on page 1of 4

Bài 1.

PASSWORD
Sub 1:
_ Duyệt i từ 1 đến N, j từ 1 đến M. Duyệt thêm 1 lần nữa để lấy ra
xâu X1..iY1..j, tống hết các xâu này vào 1 vector.
_ Khi đó ta chỉ cần kiểm tra xem trong vector có bao nhiêu xâu
phân biệt. Có nhiều cách khác nhau để xử lý bài toán này:
+ Sort vector lại theo thứ tự từ điển, kiểm tra 2 phần tử liên tiếp.
+ Sử dụng ctdl như map, set,..
+ Thay vì sử dụng vector, ta tống hết các xâu này vào 1 cây trie.
_ Độ phức tạp: O(N3 * log2(N3)) hoặc O(N3).

Sub 2:
_ Duyệt i từ 1 đến N, j từ 1 đến M. Thay vì duyệt thêm 1 lần nữa để
lấy xâu X1..iY1..j, ta chỉ cần lấy mã hash của xâu này là đủ. Có thể dễ
dàng lấy mã hash của xâu này trong O(1).
_ Khi đó, ta chỉ việc tống hết các mã hash vào 1 vector, xong kiểm
tra xem có bao nhiêu mã hash khác nhau.
_ Độ phức tạp: O(N*M * log2(N*M))
● Lưu ý:
+ Ta nên tách biệt các mã hash của các xâu độ dài
2,3,4,..,N+M riêng biệt. Tránh TH có 2 xâu khác độ dài
nhưng cùng mã hash.
+ 1 mã Hash là không đủ để qua hết mọi test. Do đó bài
này ta cần phải dùng 2 mã Hash trở lên.

Sub 3:
_ Số lượng xâu phân biệt = N*M - dp[1] - dp[2] - … - dp[N].
Trong đó:
+ dp[i] là số lượng j ∊ [1,M] mà ok(i,j) = 0.
+ ok(i,j) = 0 nếu tồn tại i’,j’ thỏa mãn:
● i’ < i
● X1..iY1..j = X1..i’Y1..j’
nếu không, ok(i,j) = 1.

_ Nhận xét: Nếu ok(i,j) = 0 thì ok(i,j-1) = 0.


=> dp[i] = j lớn nhất mà ok(i,j) = 0.
_ Gọi Z[i] = LCP(Y1..M, Yi..M). Tính hàm Z bằng cách chặt nhị phân +
Hash.
_ Xét i’, giả sử j là số lớn nhất mà tồn tại j’ thỏa mãn:
X1..iY1..j = X1..i’Y1..j’
=> X1..i’ là hậu tố của X1..i và Z[i-i’+1] = j.
=> dp[i] = max(z[i-i’+1]) với:
+ i’ = kmp[i]
+ i’ = kmp[kmp[i]]
+ ……………….
Tuy nhiên, nếu liên tục gọi i’, ta sẽ bị quá thời gian. Nên ta cải tiến
công thức trên như sau:
dp[i] = max(dp[kmp[i]], z[i-kmp[i]+1])
_ Độ phức tạp: O(N * log2(N))

Sub 4:
_ Do độ phức tạp của KMP là O(N), ta chỉ việc cải tiến độ phức tạp
của việc tính hàm Z lên O(N) bằng Z-function.
_ Độ phức tạp: O(N+M).

Câu 2: ELEMENTS
Sub 1:
_ Duyệt i từ 1 đến M, sử dụng dfs hoặc DSU để tạo ra các tplt cho
những cạnh thuộc nguyên tố i. Khi đó, với mỗi cặp đỉnh u, v cùng
thuộc 1 tplt, ++res[u][v].
_ Câu trả lời cho 1 truy vấn u,v sẽ là res[u][v].
_ Độ phức tạp: O(N*M + Q)

Sub 2:
_ Đồ thị có dạng 1 rừng gồm nhiều cây. Ta sẽ xử lý từng cây một.
Giả sử ta đang xử lý cây có gốc là root.
_ Gọi f[u] = max(d(u,v)). Trong đó:
+ v là cha của u. (v nằm trên đường đi từ root đến u)
+ d(u,v): độ dài đường đi từ u đến v.
+ Các cạnh nằm trên đường đi từ u đến v đều cùng 1 nguyên
tố.
_ Khi đó, với mỗi truy vấn x,y:
+ Nếu x, y không cùng 1 cây => Kết quả là 0.
+ Nếu x là cha của y. => Kết quả là 1 nếu f[x] ≥ d(x,y)
+ Nếu x,y không có quan hệ cha-con.
Gọi z = lca(x,y). Kết quả là 1 nếu cả 3 điều kiện sau thỏa mãn:
+ Nguyên tố thuộc cạnh (x, cha(x)) = Nguyên tố thuộc cạnh
(y,cha(y))
+ f[x] ≥ d(x,z)
+ f[y] ≥ d(y,z)

Sub 3:
_ Duyệt i từ 1 đến M, sử dụng dfs hoặc DSU để tạo ra các tplt cho
những cạnh thuộc nguyên tố i.
_ Gọi S là tập hợp các nguyên tố xuất hiện ít nhất 1 lần trong đồ thị.
Do điều kiện sub 3, |S| ≤ 300.
_ Với mỗi truy vấn (x,y), ta sẽ duyệt các nguyên tố thuộc tập S, rồi
kiểm tra xem x và y có cùng thuộc tplt ở nguyên tố đó không, nếu
có thì cộng kết quả lên 1.
_ Độ phức tạp: O(300 * Q)

Sub 4:
_ Đặt 1 số bất kỳ làm block. M nguyên tố của đồ thị sẽ thuộc 1
trong 2 loại:
+ Light: Nếu nguyên tố đó có tần số ≤ block.
+ Heavy: Nếu nguyên tố đó có tần số > block.
=> Số đỉnh heavy không quá M /block.

_ Với các đỉnh light, ta xử lý như sub 1. (Gọi res[u][v] là số lượng


nguyên tố light có thể sử dụng để đi từ u đến v).
_ Với các đỉnh heavy, ta xử lý như sub 3.
_ Kết quả bài toán sẽ là kết hợp của cả hai.

_ Độ phức tạp: O(N*block*log2(M) + Q * M /block)


=> Lấy block = 100 là tối ưu.
Câu 3: DIVIDEGROUP
Sub 1:
_ Gọi dp[i][j] là độ xung khắc nhỏ nhất nếu chia i người đầu vào j
nhóm.
_ Công thức truy hồi: dp[i][j] = min(dp[k-1][j-1] + (a[i] - a[k])2.
_ Kết quả: dp[N][K].
_ Độ phức tạp: O(K * N2)

Sub 2:
_ Cải tiến công thức QHD trên bằng CHT hoặc Li Chao.
_ Độ phức tạp: O(N * K * log2(N)).

Sub 3:
_ Điều kiện của bài toán này giúp ta cải tiến được CHT lên O(N)
(không cần chặt nhị phân mà thay bằng 2 con trỏ).
_ Độ phức tạp: O(N * K).

Sub 4: ???

You might also like