結果

問題 No.3423 Minimum Xor Query
コンテスト
ユーザー 遭難者
提出日時 2026-01-07 19:49:55
言語 C++23
(gcc 15.2.0 + boost 1.89.0)
結果
TLE  
実行時間 -
コード長 2,551 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 1,596 ms
コンパイル使用メモリ 174,920 KB
実行使用メモリ 11,300 KB
最終ジャッジ日時 2026-01-11 13:11:03
合計ジャッジ時間 14,154 ms
ジャッジサーバーID
(参考情報)
judge5 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other TLE * 1 -- * 17
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

// Gemini
#include <iostream>
#include <vector>
#include <algorithm>

// --- 最適化プラグマ ---
#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")

using namespace std;

/**
 * 20ビット(0 ~ 2^20 - 1)の整数を対象とした高速な基数ソート
 * 10ビットずつ2パスでソートを行います。
 */
void radix_sort(int r, const vector<int>& src, vector<int>& dst, vector<int>& tmp) {
    const int BITS = 10;
    const int MASK = (1 << BITS) - 1;
    const int COUNT_SIZE = 1 << BITS;

    // Pass 1: 下位10ビット
    int count1[COUNT_SIZE] = {0};
    for (int i = 0; i < r; ++i) count1[src[i] & MASK]++;
    for (int i = 1; i < COUNT_SIZE; ++i) count1[i] += count1[i - 1];
    for (int i = r - 1; i >= 0; --i) tmp[--count1[src[i] & MASK]] = src[i];

    // Pass 2: 上位10ビット
    int count2[COUNT_SIZE] = {0};
    for (int i = 0; i < r; ++i) count2[(tmp[i] >> BITS) & MASK]++;
    for (int i = 1; i < COUNT_SIZE; ++i) count2[i] += count2[i - 1];
    for (int i = r - 1; i >= 0; --i) dst[--count2[(tmp[i] >> BITS) & MASK]] = tmp[i];
}

int main() {
    // 標準入出力の高速化
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, Q;
    if (!(cin >> N >> Q)) return 0;

    vector<int> A(N);
    for (int i = 0; i < N; ++i) {
        cin >> A[i];
    }

    // 作業用バッファ(ソート用)
    vector<int> sorted_A(N);
    vector<int> tmp_buffer(N);

    while (Q--) {
        int type;
        cin >> type;
        if (type == 1) {
            int i, x;
            cin >> i >> x;
            A[i - 1] = x; // 1-indexedを0-indexedに変換
        } else {
            int r;
            cin >> r;

            // クエリ2: A[0]...A[r-1] の中から最小XORを求める
            if (r < 2) {
                // 制約上 r >= 2 ですが、念のため
                cout << 0 << "\n";
                continue;
            }

            // 1. ソート実行 (O(r))
            radix_sort(r, A, sorted_A, tmp_buffer);

            // 2. 隣接項のXORを計算
            int min_xor = 1 << 30; // 十分に大きい値
            for (int i = 0; i < r - 1; ++i) {
                int val = sorted_A[i] ^ sorted_A[i + 1];
                if (val < min_xor) {
                    min_xor = val;
                }
                // これ以上小さくなることはないので早期打ち切り
                if (min_xor == 0) break;
            }
            cout << min_xor << "\n";
        }
    }

    return 0;
}
0