Giải thuật 03/09/2026 8 phút

std::set hay bitset? Cùng một tập, chênh nhau tới 10.000 lần

Cần một tập số nguyên, cứ dùng std::set cho tiện? Tôi đo thử: với miền nhỏ dày đặc, bitset nén RAM 192 lần, phép giao nhanh 10.000 lần (AND 64 phần tử mỗi lệnh), kiểm tra thành viên nhanh 870 lần. Nhưng miền rộng tập thưa thì bitset lại phí RAM — chọn theo miền nhỏ/rộng, dày/thưa.

Giải thuật 03/09/2026 7 phút

s = s + x trong vòng lặp: quả bom O(N²) khiến 20 triệu ký tự mất 72 phút

Nối chuỗi trong vòng lặp s = s + phần trông vô hại? Tôi đo thử: với chuỗi bất biến (tạo chuỗi mới mỗi lần), nối 200 nghìn ký tự đã copy 20 tỷ byte — O(N²), 2151 ns/ký tự; nếu 20 triệu thì mất 72 phút. Buffer/StringBuilder append tại chỗ chỉ 2,18 ns/ký tự, O(N) — nhanh hơn 1000 lần mỗi ký tự.

Giải thuật 03/09/2026 8 phút

Trie không 'tốt hơn' hash — nó làm được thứ hash chịu thua

Trie luôn tốt hơn hash cho chuỗi? Tôi đo thử: trie tốn RAM gấp 11 lần hash (256 MB vs 23 MB) và exact match chỉ ngang nhau. Nhưng trie thắng tuyệt đối một việc hash không làm nổi: tra tiền tố / autocomplete — 94 lần nhanh hơn, vì hash phải quét toàn bộ tập. Chọn theo có cần prefix hay không.

Giải thuật 03/09/2026 8 phút

Bỏ con trỏ, dùng chỉ số: cây nhỏ hơn 33% và nhanh hơn 1,86 lần

Cây và list phải dùng con trỏ, đó là cách chuẩn? Tôi đo thử: thay con trỏ 8 byte bằng chỉ số 4 byte vào một arena làm node nhỏ hơn 33%, RAM ít hơn 33%, và tra cứu nhanh 1,86 lần — vì node nằm liền mạch thay vì malloc rải rác. Con trỏ không phải lựa chọn duy nhất, và thường không phải lựa chọn tốt nhất.