結果

問題 No.1456 Range Xor
ユーザー cutmdo
提出日時 2023-01-14 10:59:08
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 88 ms / 2,000 ms
コード長 3,094 bytes
コンパイル時間 1,216 ms
コンパイル使用メモリ 112,140 KB
最終ジャッジ日時 2025-02-10 03:28:24
ジャッジサーバーID
(参考情報)
judge1 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 46
権限があれば一括ダウンロードができます

ソースコード

diff #

#define PROBLEM "https://yukicoder.me/problems/no/1456"

#include <iostream>
#include <unordered_set>

#include <vector>
#include <cmath>

template <class SG>
class DisjointSparseTable {

    using S = decltype(SG::Type());

    const int m_n;
    const std::vector<std::vector<SG>> m_table;

    static auto accumulation(int n, const std::vector<S>& a, int l, int r) {
        auto mid = (r + l) >> 1;
        r = std::min(n, r);
        int size = r - l;
        std::vector<SG> acc; acc.reserve(size);
        for(int i = l; i < r; ++i) { acc.emplace_back(a[i]); }
        for(int i = mid - 2; i >= l; --i) if(i - l + 1 < size) {
            acc[i - l] = acc[i - l].binaryOperation(acc[i - l + 1]);
        }
        for(int i = mid + 1; i < r; ++i)if(i - l - 1 >= 0) {
            acc[i - l] = acc[i - l - 1].binaryOperation(acc[i - l]);
        }
        return acc;
    }

    static auto constructTable(int n, const std::vector<S>& a) {
        std::vector<std::vector<SG>> table; table.reserve(std::log2(n) + 1);
        table.emplace_back(a.begin(), a.end());

        auto size = 1;
        while(size < n) {
            size <<= 1;
            std::vector<SG> acc; acc.reserve(n);
            for(int l = 0; l < n; l += size) for(const auto& x : accumulation(n, a, l, l + size)) {
                acc.emplace_back(x);
            }
            table.emplace_back(acc);
        }
        return table;
    }

    static auto msb(int x) {
        auto idx = 0;
        while(x > 0) { ++idx; x >>= 1; }
        return idx;
    }
public:
    DisjointSparseTable(int n, const std::vector<S>& a) :m_n(n), m_table(constructTable(n, a)) {}

    auto get(int l, int r)const {
        if(r < l) { throw std::runtime_error("ERROR! `l` must less than `r`"); }
        l = std::max(l, 0); r = std::min(r, m_n - 1);
        if(l == r) { return m_table[0][l].m_val; }
        auto idx = msb(l ^ r);
        return m_table[idx][l].binaryOperation(m_table[idx][r]).m_val;
    }
};
template<
    class S,// 要素の型
    class T // 2項演算子
>
struct SemiGroup {
    static inline auto Type() { return S(); }
    S m_val;
    SemiGroup(S val) :m_val(val) {}
    SemiGroup binaryOperation(const SemiGroup& m2)const { return T()(m_val, m2.m_val); }
    friend std::ostream& operator<<(std::ostream& os, const SemiGroup<S, T>& m) {
        return os << m.m_val;
    }
};

using ll = long long;
using std::cout;
using std::cin;
constexpr char endl = '\n';

struct F { auto operator()(ll x, ll y) { return x ^ y; } };
using SG = SemiGroup<ll, F>;

signed main() {
    ll n, k;
    cin >> n >> k;

    std::vector<ll> a; a.reserve(n);
    for(int _ = 0; _ < n; ++_) {
        ll x; cin >> x;
        a.emplace_back(x);
    }

    auto dst = DisjointSparseTable<SG>(n, a);
    std::unordered_set<ll> st;
    for(int i = 0; i < n; ++i) {
        st.emplace(dst.get(0, i) ^ k);
    }

    if(st.find(0) != st.end()) { cout << "Yes" << endl; return 0; }
    for(int i = 0; i < n; ++i) {
        if(st.find(dst.get(0, i)) != st.end()) { cout << "Yes" << endl; return 0; }
    }
    cout << "No" << endl;
}
0