我们拿到一个数组a,要求数组a的任意一个区间的所有数字的异或和不能为0或x。
首先,如果对于数组a,我们有他的前缀异或合数组b,那么数组a的任何一个区间的所有元素的异或和都可以用b中两个元素的异或和表示,那么我们就将问题转化为,最多可以有多少个数字两两异或不为0或x。对于这个问题,我们只需要从1到2n遍历,如果i没有被选取过,那就就选取他,顺便禁用i^x.
还有一个要注意的细节就是元素的个数可能为0,会runtime error
#include <iostream>
#include <math.h>
#include <iomanip>
#include <string>
#include <cstdio>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define INF 0x3f3f3f3f
#define N 1<<18
#define ll long long
using namespace std;
bool vis[N+1];
vector<int>a;
int n,x;
int main() {
int i, j;
scanf("%d%d",&n,&x);
for(i=1;i<pow(2,n);i++){
if(vis[i] || i == x){
continue;
}else
{
a.push_back(i);
vis[i] = 1;
//if((i^x) < N){
vis[i^x] = 1;
//}
}
}
printf("%d\n",a.size());
if(a.size() == 0){
return 0;
}
printf("%d ",a[0]);
for(i=1;i<a.size();i++){
printf("%d ",a[i]^a[i-1]);
}
printf("\n");
return 0;
}