trang chủ / đề bài / pfxortrie / lời giải

XOR đoạn con lớn nhất

Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
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.
Tác giả: huunguyenhuunguyen

Hướng tiếp cận

Đây là một bài toán kinh điển kết hợp XOR tiền tố với trie nhị phân để tìm cặp giá trị có XOR lớn nhất.

Nhận xét quan trọng

Đặt p0=0 và pi=a1⊕a2⊕⋯⊕ai với 1≤i≤n. Vì XOR là phép có nghịch đảo bằng chính nó nên XOR của đoạn [l,r] là

al⊕al+1⊕⋯⊕ar=pr⊕pl−1.

Bài toán trở thành: cho tập {p0,p1,…,pn}, tìm cặp (i,j) với 0≤i<j≤n sao cho pi⊕pj là lớn nhất.

Khi cho phép i≤j thì cặp (j,j) luôn cho giá trị 0, nên kể cả nếu coi i=j là hợp lệ cũng không ảnh hưởng cực đại — miễn là tập có ít nhất hai phần tử (luôn đúng vì p0 luôn có mặt).

Thuật toán

Duyệt theo thứ tự j=0,1,…,n và duy trì một trie nhị phân 30 bit (bit cao → bit thấp) chứa các giá trị p0,p1,…,pj−1.

  1. Khởi tạo trie rỗng rồi insert p0=0. Đây là bước bắt buộc: nếu thiếu, các đoạn dạng [1,r] sẽ không được xét vì pr⊕p0=pr không có cách nào sinh ra.
  2. Với mỗi j từ 1 đến n:
    • Truy vấn trie để tìm giá trị x trong trie cực đại hoá x⊕pj: đi từ bit cao xuống bit thấp; tại mỗi bit, ưu tiên rẽ sang nhánh có bit ngược với bit hiện tại của pj (nếu nhánh đó tồn tại), ngược lại đi theo nhánh còn lại.
    • Cập nhật đáp án: ans←max(ans,x⊕pj).
    • Insert pj vào trie.
  3. Khi n=1, trie ban đầu chứa p0=0, truy vấn cho p1=a1 trả về 0⊕a1=a1 — đúng đáp án.
Cài đặt trie mảng (C++)

Dùng hai mảng nxt[N*30 + 10][2] để biểu diễn cây. Mỗi lần insert/query là O(30). Tổng cộng O(30n) ô nhớ.

Cài đặt Python

Vì Python chậm hơn nhiều lần, ta dùng trie dạng mảng phẳng nxt = [[0,0]] * (n*30 + 5) (cấp phát một lần) và sử dụng các phép dịch bit. Đọc dữ liệu bằng sys.stdin.buffer.read() để tăng tốc.

Độ phức tạp

  • Thời gian: O(30n).
  • Bộ nhớ: O(30n) cho trie.

Bình luận

Không có bình luận tại thời điểm này.

gnatmake 12.2.0 a68g 3.1.2 nasm 2.16.1 as_x64 2.47 awk 1.3.4 gcc 16.2.0 dotnet 10.0.402 g++ 16.2.0 g++-themis 16.2.0 g++17 16.2.0 g++20 16.2.0 g++23 16.2.0 clang++ 22.1.8 dmd 2.113.0 dart 3.13.6 gforth 0.7.3 gfortran 15.3.0 go 1.27.3 groovyc 5.1.3 javac 26.0.2.1 node 26.12.1 julia 1.13.2 kotlinc 2.4.21 lean 4.35.0 sbcl 2.2.9 lua 5.5.1 nim 2.2.12 fpc 3.2.2 fpc-themis 3.2.2 perl 5.42.3 php 8.5.12 pike 8.0 swipl 9.0.4 pypy3 7.3.23 python3 3.15.1 racket 8.7 ruby 4.0.8 rustc 1.99.1 csc 5.3.0 ctoj-scratch 0.0.1 sed 4.9 swiftc 6.4.1 tclsh 8.6 bun 1.4.4 deno 2.9.8 v 0.5.2 zig 0.17.0