鏈接
[https://codeforces.com/contest/1174/problem/D]
題意
讓你構造一個數組,使得任意子段異或和不為0也不為x,而且每個數字大於等於1小於(1<<n)
分析
比賽做不出來,還是太垃圾了,這只能說水平不夠。而且我對位運算的題真的不敏感。
以后專門刷下位運算題。
我是看官方題解,知道的。首先有前綴異或和數組。
al⊕al+1⋯⊕ar=bl−1⊕br.,好有了這個之后,我們反向先把前綴異或和數組求出來。
對於a的任意子段都可以從b數組得到。看哪個表達式就知道了,那么使得a任意子段異或和不為0也不為x,
那么b的任意兩兩不能相等,如果有相等,就一定有某個子段a為0.為了a任意子段異或也不為x,那么b兩兩不能異或和為x.
既然把b求出來了,ai=bi⊕bi−1.這技巧確實學到了,而且對異或的性質更加深入了。
代碼
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e6;
int s[N];
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n,x;
while(cin>>n>>x){
set<int> se;
int cnt=0;
se.insert(0);
for(int i=1;i<(1<<n);i++){
if(!se.count(i^x)){
s[++cnt]=i;
se.insert(i);
}
}
cout<<cnt<<endl;
for(int i=1;i<=cnt;i++)
cout<<(s[i]^s[i-1])<<' ';
cout<<endl;
}
return 0;
}