結果
| 問題 | No.1456 Range Xor |
| コンテスト | |
| ユーザー |
cutmdo
|
| 提出日時 | 2023-01-14 10:59:08 |
| 言語 | C++17 (gcc 15.2.0 + boost 1.89.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 |
ソースコード
#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;
}
cutmdo