Hướng dẫn giải của Mofk Cup Round 2 - SUFFIX ARRAY
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.
Đầu tiên, nếu ~p~ là dãy giảm thì đáp án là ~n + 1~, các xâu thỏa mãn lần lượt là "000...0", "100...0", "110...0", "111...0", ..., "111...1". Đây là trường hợp mà ~Mofk~ khóc thét vì quá nhiều xâu ~s~ tồn tại.
Nếu ~p~ không là dãy giảm, gọi ~L~ là độ dài dài nhất của đoạn tiền tố thỏa mãn ~p[i] = n - i + 1~ với mọi ~i~. Lúc này ~s[p[i]] = 0~ với mọi ~i \leq L~, vì nếu ~s[p[i]]~ = 1 với giá trị ~i \leq L~ nào đó, thì tất cả giá trị ~s[p[i + 1]], s[p[i + 2]],..., s[p[n]]~ đều phải bằng ~1~, nghĩa là ~s~ có dạng "111...11000...0", mà dãy hậu tố của dạng này phải là dãy giảm, mâu thuẫn với điều kiện ~p~ không là dãy giảm.
Vậy sau khi tìm ~L~ và xử lý được đoạn tiền tố của ~p~, ta còn lại đoạn ~p[L + 1..n]~ hợp với ~s[1..n - L]~. Gọi ~j~ là vị trí của ~n - L~ trong ~p~ (~p[j] = n - L~, lưu ý rằng ~j > L + 1~ theo định nghĩa của ~L~ bên trên). Lúc này ta có ~s[p[j]] = 1~, bởi nếu ~s[p[j]] = 0~ thì ~j~ phải bằng ~L + 1~ (vì đoạn s[n - L..n] khi đó sẽ toàn giá trị ~0~).
Khi ~s[p[j]] = 1~, nghĩa là s[n - L..n] = "1000...0", là xâu nhỏ nhất bắt đầu bằng ~1~, vậy nên các xâu hậu tố khác muốn nhỏ hơn ~s[n-L..n]~ thì chỉ có thể bắt đầu bằng ~0~, nghĩa là ~s[p[k]] = 0~ với mọi ~k < j~. Cuối cùng, theo định nghĩa của dãy hậu tố, ta có ~s[p[k]] = 1~ với mọi ~k > j~.
Nói tóm gọn, từ các giá trị ~L, j~, ta xác định được xâu ~s~ duy nhất có khả năng nhận ~p~ làm dãy hậu tố. Ta chỉ cần kiểm tra xem xâu ~s~ có thực sự nhận ~p~ là hậu tố hay không. Nếu có, đáp án là ~1~ và ~Mofk~ sẽ rất vui mừng vì đền được binh khí cho thầy, nếu không, đáp án là ~0~ và ~Mofk~ sẽ rơi vào trạng thái hoang mang tột độ vì không những làm hỏng binh khí mà còn tìm sai luôn cái dãy ~p~.
Bình luận