CodeForces.1174D.EhabandtheExpectedXORProblem(构造前缀异或和数组)

  题目连接数组

这道题比赛的时候没作出来,赛后补题的时候发现其实能够构造一个前缀异或和数组,而后根据初始化的第一个值进行填数,可是做为菜鸡的我虽然坚信本身的想法是正确的却想了好久也没有可以构造出来所谓的前缀异或和数组。唉,嘤嘤嘤spa

  本题思路:咱们能够根据这个构造一个前缀异或和数组,由ans[ i ] ^ ans[ i - 1 ]就能够获得数组里第i个元素的值。code

  如何构造这个前缀数组呢,咱们暂时把咱们构造的前缀数组叫作b,最后输出的答案数组称做a,那么咱们能够知道,a [ l ] ^ a[l + 1] ^ .... ^ a[ r ] = b[ r ] ^ b[l - 1]。因此这个问题也就变成了,咱们要构造一个blog

前缀数组,使得任意两个数字的异或和不为x且每次数字只使用一次.(为了不0的出现),因此咱们知道两个异或和为x的数字咱们只能选择其中一个。get

  Can anyone explain me why it's 1 to 2^n - 1?it

#include <cstdio>
#define len 1 << n
#include <vector>
#include <algorithm>
using namespace std;

const int maxn = 1 << 18;
int value[maxn];
vector <int> ans;

int main() {
    int n, x;
    scanf("%d %d", &n, &x);
    ans.push_back(0);
    for(int i = 1; i < len; i ++) {
        if(i != x) {
            if(value[i]) continue;//只选用未标记的
            ans.push_back(i);
            value[x ^ i] = 1;//不能选择和i异或获得x的数字
        }
    }
    printf("%d\n", ans.size() - 1);
    for(int i = 1; i < ans.size(); i ++) {
        if(i > 1)   printf(" ");
        printf("%d", ans[i] ^ ans[i - 1]);
    }
    printf("\n");
    return 0;
}
相关文章
相关标签/搜索