Codeforces Round #563 (Div. 2) D. Ehab and the Expected XOR Problem(异或前缀和)

题目链接:https://codeforces.com/contest/1174/problem/D

题意

给出 $n$ 和 $x$,构造一个数组 $a$,要求:

  • $1 ≤ a_i < 2^n$
  • 对任意 $l \le r$,$a_l \oplus a_{l+1} \dots \oplus a_r$ 不为 $0$ 或 $x$
  • 数组尽可能地大

($1 \le n \le 18, 1 \le x < 2^{18}$)

题解

异或前缀和:\begin{equation} a_l \oplus a_{l+1} \dots \oplus a_r=b_{l-1} \oplus b_{r} \end{equation}

因为数组 $a$ 的每个区间异或值都可以视为数组 $b$ 中的两个元素相异或,所以只要数组 $b$ 满足元素两两异或值不为 $0$ 或 $x$,再由 $a_i = b_i \oplus b_{i - 1}$ 得到数组 $a$ 即可。

如果 $x < 2^n$,对于每个 $b_i$ 一定存在一个唯一的值使得二者异或后为 $x$,且这样相互异或为 $x$ 的数是成对独立的,一对数中取其中较小者。

代码

#include <bits/stdc++.h>
using namespace std;
bool ex[(1 << 18)];
int main() {
    int n, x; cin >> n >> x;
    vector<int> b;
    b.push_back(0);
    ex[0] = true;
    for (int i = 1; i < (1 << n); i++) {
        if (ex[x ^ i]) continue; //一对数中取其一
        b.push_back(i);
        ex[i] = true;
    }
    cout << b.size() - 1 << "\n";
    for (int i = 1; i < b.size(); i++)
        cout << (b[i] ^ b[i - 1]) << ' ';
}

 

posted @ 2020-06-13 20:27  Kanoon  阅读(139)  评论(0)    收藏  举报