Bài 1
Vì ta chỉ xét một đoạn liên tiếp, nên ta biết được rằng, các kí tự ngoặc đóng sẽ luôn match kí tự ngoặc mở gần nhất bên trái giống y như việc match khi xét cả xâu . (nếu bài là subsequence sẽ không match được như vậy).
Với mỗi vị trí , ta sẽ tìm vị trí sao cho match được một dãy ngoặc đúng. Khi đó ta sẽ coi dãy ngoặc này là một dãy ngoặc độc lập (không có dãy nào bao nó). Gọi là đáp án khi xét dãy kết thúc tại . Khi đó ta có lựa chọn là:
- Lấy dãy hiện tại nối vào .
- Chỉ lấy dãy .
- Lấy dãy empty.
Bài 2
Gọi là số dãy có hai phần tử cuối là và . Với mọi sao cho , ta cập nhật .
Làm như trên sẽ mất độ phức tạp là . Để cải tiến lên thì ta thấy chỉ có duy nhất một không thoả mãn. Do đó ta có thể cộng tổng hết và trừ đi .
Giờ ta sẽ giảm xuống chỉ còn một chiều: là số dãy có kết thúc là . Với mọi , ta thực hiện thao tác nếu . Cách làm trên vẫn có độ phức tạp là nhưng ta lại có thể cải tiến được.
Thật vậy, ta lưu thêm mảng tổng tiền tố là tổng các từ đến . Lúc này . Việc cần làm bây giờ là nhóm hết những thoả mãn vào để trừ cho nhanh.
Gọi bit cao nhất của là . Ta thấy bit cao nhất của tối đa là . Nếu bit thứ của là , thì . Nếu bit thứ của là thì (thoả mãn). Vậy ta sẽ chỉ trừ với những có bit cao nhất bằng bit cao nhất của . Dù đã giảm được cơ số phải xét nhưng ta vẫn không thể lưu hoặc xét được mọi được vì thay đổi cũng như có quá nhiều .
Giờ ta sẽ làm ngược một chút. Đặt .
- Điều kiện đầu tiên là bit cao nhất của phải khác bit cao nhất của và (vì bit cao nhất của bằng bit cao nhất của => bit tại vị trí đó của là , khác và ).
- Điều kiện tiếp theo là .
Ta sẽ trừ hết tất cả các thoả mãn như trên (tính đúng đắn được đảm bảo).
Làm ngược như vậy có tác dụng gì? Lúc này khi duyệt tăng dần, khi nào bit cao nhất của tăng lên một vị trí, ta mới đi cập nhật các trước đó. Ngoài ra điều kiện sẽ dễ kiểm soát với là tham số hơn. Có thể dùng trie để trừ đi các như trên.
Bài 3
Có thể tóm gọn đề bài là tính diện tích lớn nhất của tplt. Pha tính phần diện tích hợp thì dễ, xử lí như bài Area. Giờ ta chỉ quan tâm pha DSU để hợp nhất các hcn thuộc một tplt.
Ta sẽ sweepline theo và merge những thằng có giao nhau. Lưu lại các đoạn theo trong vector trên các node của segtree. Khi merge thì ta chỉ việc lấy ra. Tuy nhiên nếu không có theo trick thì độ phức tạp sẽ rất lớn. Ta để ý là sau khi merge, chỉ cần lưu đúng 1 phần tử là đại diện được cho tplt. Ta sẽ lưu phần tử bị xoá cuối cùng khi sweepline. Lúc đó ta se có cơ hội merge càng nhiều.
Tuy sol ngắn nhưng code khá ảy chỉa. Các em tự code nhé 😉