又是神仙题。
不过发现1900分的题很多都是转化为前缀(后缀)和数组来解决问题的
A 数 组 不 好 构 造 , 考 虑 构 造 A 的 前 缀 异 或 数 组 s A数组不好构造,考虑构造A的前缀异或数组s A数组不好构造,考虑构造A的前缀异或数组s
那 么 有 a i = s i ⊕ s i − 1 那么有a_i=s_i{\oplus} s_{i-1} 那么有ai=si⊕si−1
那么现在就是看这个s数组的限制
Ⅰ . 异 或 后 值 域 不 变 , 所 以 s 数 组 也 取 [ 1 , 1 < < n ) Ⅰ.异或后值域不变,所以s数组也取[1,1<<n) Ⅰ.异或后值域不变,所以s数组也取[1,1<<n)
Ⅱ . 由 于 不 出 现 子 段 异 或 和 为 0 , 所 以 s 数 组 中 任 意 元 素 不 相 等 Ⅱ.由于不出现子段异或和为0,所以s数组中任意元素不相等 Ⅱ.由于不出现子段异或和为0,所以s数组中任意元素不相等
换 言 之 , [ 1 , 1 < < n ) 中 的 数 最 多 用 1 次 换言之,[1,1<<n)中的数最多用1次 换言之,[1,1<<n)中的数最多用1次
Ⅲ . 若 s 数 组 出 现 了 s i , 就 不 能 出 现 s i ⊕ x , 这 就 保 证 没 有 字 段 异 或 为 x Ⅲ.若s数组出现了s_i,就不能出现s_i\oplus{x},这就保证没有字段异或为x Ⅲ.若s数组出现了si,就不能出现si⊕x,这就保证没有字段异或为x
那 么 , 由 于 选 w , 就 会 删 去 w ⊕ x \color{Red}那么,由于选w,就会删去w\oplus{x} 那么,由于选w,就会删去w⊕x
且 对 于 不 同 的 w , 删 去 的 w ⊕ x 都 是 不 同 的 且对于不同的w,删去的w\oplus{x}都是不同的 且对于不同的w,删去的w⊕x都是不同的
说 明 , [ 1 , 1 < < n ) 中 的 元 素 我 们 可 以 选 一 半 说明,[1,1<<n)中的元素我们可以选一半 说明,[1,1<<n)中的元素我们可以选一半
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
#define quickly ios::sync_with_stdio(false)
bool vis[1<<18];
int n,x;
vector<int>ans;
int main()
{
quickly;
cin >> n >> x;
vis[x]=1;
ans.push_back(0);
for(int i=1;i< (1<<n) ;i++)
{
if( vis[i] ) continue;
ans.push_back(i);//选i,就不能选i^x
vis[i]=vis[i^x]=1;
}
cout << ans.size()-1 << endl;
for(int i=1;i<ans.size();i++)
cout << ( ans[i]^ans[i-1] ) << " ";
return 0;
}