Codeforces 1174D:Ehab and the Expected XOR Problem 题解

主要思路

这道题还蛮妙的,自己比较顺利的思考出来了。

考虑设置前缀异或和\(\{ S_i \}\),根据异或按位处理的性质,显然对于所有的\(S_i\)都会小于\(2^n\)。最后,我们可以把限制变成:

  • 不存在两个相同的前缀和。
  • 不存在一对前缀和,其异或值为\(x\)。

针对\(x\)的大小关系,我们可以分成两种情况:

  • \(x \geq 2^n\),不存在一对\((S_i, S_j)\)的异或为\(x\),因为存在更高的位并不会被消除。
  • \(x < 2^n\),我们发现每选择一个数作为前缀和,整个\(2^n\)中就会少一个对应的可以被选择的数。所以,我们每次选一个作为\(S_i\)的数时,都要把\(S_i xor \ x\)打标记。

结合一下就可以了。

代码

// CF1174D.cpp
#include <bits/stdc++.h>

using namespace std;

const int MAX_N = (1 << 18) + 200;

int n, x, seq[MAX_N];
bool vis[MAX_N];

int main()
{
    scanf("%d%d", &n, &x);
    if (x >= (1 << n))
    {
        int len = (1 << n) - 1;
        printf("%d\n", len);
        for (int i = 1; i <= len; i++)
            printf("%d ", i ^ (i - 1));
    }
    else
    {
        vis[x] = true;
        int tot = 0;
        for (int i = 1, last = 0; i < (1 << n); i++)
            if (vis[i] == false)
                vis[i ^ x] = true, seq[++tot] = i ^ last, last = i;
        printf("%d\n", tot);
        for (int i = 1; i <= tot; i++)
            printf("%d ", seq[i]);
    }
    return 0;
}

Leave a Reply

Your email address will not be published. Required fields are marked *