Hướng dẫn giải của Clue Contest 06 - Impossible


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ả: Yamiza_Zinno

Nhận xét

  • OR chỉ bật thêm bit ~1~, không bao giờ tắt bit đã có Khi bạn OR một tập các số, mọi bit 1 của từng số đều được giữ lại, và chỉ có thể "mở" thêm các bit ~1~ mới từ các số đó.

  • Hệ quả: Để tạo ra một số ~x~ bằng OR của một tập con của ~A~, thì:

    • Mỗi bit 1 của ~x~ phải có ít nhất một số trong tập con đó cũng có bit 1 ở vị trí tương ứng (để "bật" bit này).
    • Không thể tắt bất kỳ bit ~1~ không mong muốn nào: nếu bạn chọn một số có thêm bit ~1~ ngoài những bit của ~x~, kết quả OR sẽ bật luôn những bit đó và vượt quá ~x~.
  • Theo đó, nếu trong mảng ~A~ hoàn toàn không có bất kỳ số nào bật bit ~k~ (tức không có số nào có ~2^k~ trong thành phần nhị phân), thì bạn không thể tạo ra bất kỳ số ~x~ nào có bit ~k = 1~.

Chính vì thế,ta có thể nhận thấy số dương nhỏ nhất không thể biểu diễn được chính là lũy thừa của ~2~ nhỏ nhất mà ~A~ không chứa.

Để chặt chẽ hơn, ta sẽ chứng minh rằng:

Số dương nhỏ nhất không thân thiện với ~A~ là ~2^k~, trong đó ~k~ là số mũ nhỏ nhất sao cho không tồn tại ~A_i = 2^k~.

Chứng minh phản chứng

Giả sử ~x~ là số dương nhỏ nhất không thân thiện với ~A~, nhưng ~x~ không phải là lũy thừa của ~2~.

Vì ~x~ không phải lũy thừa của ~2~, trong biểu diễn nhị phân của ~x~ có ít nhất hai bit 1. Ta viết

$$ x \;=\; a\;+\;b, $$

trong đó

  • ~a~ chỉ lấy các bit ~1~ tách ra phần thấp hơn,
  • ~b~ chỉ lấy các bit ~1~ tách ra phần cao hơn,
  • Thỏa mãn ~0 < a < x~, ~0 < b < x~, và ~a~ với ~b~ không cùng bật bit nào (hai nhị phân của ~a~ và ~b~ không chồng chéo bit 1).

Ví dụ: nếu ~x = 13 = 1101_2~, ta có thể chọn ~a=5=0101_2~, ~b=8=1000_2~.

  • Vì ~a < x~ và ~b < x~ và ~x~ là số nhỏ nhất không thân thiện, nên cả ~a~ và ~b~ đều thân thiện với ~A~ (vì nếu ~a~ hoặc ~b~ mà không thân thiện mà ~a < x~ và ~b < x~ dẫn đến ~x~ không còn là số nhỏ nhất nữa).

    • Tức là có một dãy chỉ số ~i_1<\cdots<i_p~ sao cho</p>

      $$ A_{i_1}\;\bigl|\;\cdots\;\bigl|\;A_{i_p} \;=\; a $$

    • Và có một dãy chỉ số ~j_1<\cdots<j_q~ sao cho</p>

      $$ A_{j_1}\;\bigl|\;\cdots\;\bigl|\;A_{j_q} \;=\; b $$

  • Vì ~a~ và ~b~ bật các bit ~1~ ở các vị trí khác nhau, khi ta lấy hợp ~\{i_1,\dots,i_p\}\cup\{j_1,\dots,j_q\}~ (sắp theo thứ tự tăng) thì

$$ \Bigl(A_{i_1}\;\bigl|\;\cdots\;\bigl|\;A_{i_p}\Bigr) \;\bigl|\; \Bigl(A_{j_1}\;\bigl|\;\cdots\;\bigl|\;A_{j_q}\Bigr) \;=\; a\;\bigl|\;b \;=\; x. $$

Và vì trong các chỉ số ~i~ với ~j~ không có xung đột (chúng ta chỉ cần sắp lại hai dãy con cho thành một dãy con tăng), nên ~x~ có thể được biểu diễn dưới dạng OR của một tập con của ~A~.

~\longrightarrow~ Điều này mâu thuẫn với giả thiết "~x~ không thân thiện"

Phản chứng trên cho thấy không tồn tại số ~x~ nhỏ nhất không thân thiện mà không phải lũy thừa của 2.

~\Longrightarrow~ Vậy số dương nhỏ nhất không thân thiện với ~A~ phải là một lũy thừa của ~2~, tức ~x \;=\; 2^k~ với ~k~ là chỉ số nhỏ nhất sao cho không có ~A_i = 2^k~.

#include <bits/stdc++.h>
using namespace std;

void sol(){
    int n; cin >> n;
    vector <int> a(n);
    for(int &x : a) cin >> x;
    unordered_set<int> s;
    for (int x : a) if ((x & (x - 1)) == 0) s.insert(x);
    int ans = 1;
    while (s.count(ans)) ans <<= 1;
    cout << ans << "\n";
}

int main(){
    int t; cin >> t;
    while(t--) sol();
}


Bình luận

Hãy đọc nội quy trước khi bình luận.


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