Editorial for Xử lí bit cơ bản


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Author: UltimateWiener

tag: dynamic programming, trie, small to large, centroid decomposition.

Đầu tiên, cho mình xin lỗi vì đề bài ngu của LKT.

Tóm tắt ngắn gọn lại đề bài: Cho một cây gồm N đỉnh, độ tuyệt vời của cặp đỉnh (u,v) là tổng xor của đường đi đơn từ u đến v. Bạn cần tìm độ tuyệt vời lớn nhất của mọi cặp (u,v) và đếm xem có bao nhiêu cặp có độ tuyệt vời bằng độ tuyệt vời lớn nhất đấy.

Subtask 1

Làm gì cũng được.

ĐPT: O(hio)

Subtask 2

Với mỗi đỉnh u ta tiến hành dfs hoặc bfs để tính độ đẹp của đỉnh u tới mọi đỉnh v khác, sau đó tính đáp án theo đề bài.

ĐPT: O(N2)

Subtask 3

Ai1, nên độ tuyệt vời lớn nhất của đồ thị chính là 1. Nên nếu không tồn tại một đường đi có độ tuyệt vời là 1 thì độ tuyệt vời của đồ thị sẽ bằng 0 và số cặp thỏa mãn sẽ là N2. Nếu có tồn tại, chúng ta sẽ tiến hành đếm số đường đi có độ tuyệt vời là 1 như sau:

Gọi s(u,v) là độ đẹp của cặp (u,v), fu là số đỉnh con v sao cho s(u,v)=1, gu là số đỉnh con v sao cho s(u,v)=0.

Ta dễ dàng tính fugu bằng công thức sau:

  • Nếu Au=1:

    • fu=1+gv

    • gu=fv

  • Nếu Au=0:

    • fu=fv

    • gu=1+gv

Trong đó, v là đỉnh con trực tiếp của u.

Khi có được fugu, ta có thể dễ dàng tính được đáp án (mời bạn đọc tự tính do mình lười).

ĐPT: O(N)

Subtask 4

Gọi fu,i là số đỉnh con v sao cho s(u,v)=i.

Ta dễ dàng tính được fu,i bằng công thức sau: fu,i=fv,j với mọi j,v thỏa mản jAu=iv là đỉnh con trực tiếp của u (Tất nhiên, fu,Au được cộng thêm 1).

(Mình quên mất phần sau nên mình mời bạn đọc làm tiếp subtask này).

ĐPT: O(N×322)

Subtask 5

Để giải quyết được subtask cuối cùng, chúng ta cần giải quyết được bài toán dễ hơn:

"Cho 1 dãy gồm N số không âm, tìm tổng xor lớn nhất của một đoạn liên tiếp của mảng này".

Duyệt trâu thông thường sẽ có ĐPT là O(N2), sẽ không qua được giới hạn của bàn toán. Để tối ưu hóa, chúng ta để ý rằng tổng xor của đoạn [l...r]prefrprefl1 với prefi là tổng xor của đoạn [1...i]. Ta cố định prefr, với mỗi r (1rN) ta cần tìm l (lr) sao cho prefrprefl1 lớn nhất. Ta duy trì một trie lưu các giá trị pref1,pref2,...,prefr, rồi xét từ bit lớn nhất tới bit nhỏ nhất, mỗi lần như vậy ta kiểm tra xem có tồn tại prefi sao cho bit lớn thứ j bit lớn thứ j của prefr có bằng 1 hay không. Với cách làm này, ta giảm ĐPT từ O(N2) xuống O(N×log2(max(Ai))). VNOI wiki cũng có phần nói về bài này Link.

Trở về bài toán chính, với mỗi đỉnh u chúng ta có thể lưu một trie chứa các giá trị s(u,v). Để gộp trie một cách hiệu quả, ta sử dụng kỹ thuật small to large. Trong quá trình gộp, ta lấy toàn bộ giá trị ở trie nhỏ hơn, rồi coi thử xem giá trị xor lớn nhất với trie lớn hơn là bao nhiêu bằng tư duy trên.

ĐPT: O(N×log2(max(Ai))2)

Tài liệu tham khảo


Comments

Please read the guidelines before commenting.


There are no comments at the moment.